Ignore:
Timestamp:
Oct 21, 2024, 7:05:31 PM (17 hours ago)
Author:
abarral
Message:

(cont.) Convert fixed-form to free-form sources .F -> .{f,F}90

File:
1 moved

Legend:

Unmodified
Added
Removed
  • LMDZ6/trunk/libf/dyn3dmem/vlsplt_loc.F90

    r5247 r5248  
    22! $Id$
    33!
    4       RECURSIVE SUBROUTINE vlx_loc(q,pente_max,masse,u_m,ijb_x,ije_x,iq)
    5 
    6 c     Auteurs:   P.Le Van, F.Hourdin, F.Forget
    7 c
    8 c    ********************************************************************
    9 c    Shema  d'advection " pseudo amont " .
    10 c    ********************************************************************
    11 c    nq,iq,q,pbaru,pbarv,w sont des arguments d'entree  pour le s-pg ....
    12 c
    13 c
    14 c   --------------------------------------------------------------------
    15       USE parallel_lmdz
    16       USE infotrac, ONLY : nqtot,tracers, ! CRisi                 &
    17      &                     min_qParent,min_qMass,min_ratio ! MVals et CRisi
    18       IMPLICIT NONE
    19 c
    20       include "dimensions.h"
    21       include "paramet.h"
    22       include "iniprint.h"
    23 c
    24 c
    25 c   Arguments:
    26 c   ----------
    27       REAL masse(ijb_u:ije_u,llm,nqtot),pente_max
    28       REAL u_m( ijb_u:ije_u,llm),pbarv( iip1,jjb_v:jje_v,llm)
    29       REAL q(ijb_u:ije_u,llm,nqtot) ! CRisi: ajout dimension nqtot
    30       REAL w(ijb_u:ije_u,llm)
    31       INTEGER iq ! CRisi
    32 c
    33 c      Local
    34 c   ---------
    35 c
    36       INTEGER ij,l,j,i,iju,ijq,indu(ijnb_u),niju
    37       INTEGER n0,iadvplus(ijb_u:ije_u,llm),nl(llm)
    38 c
    39       REAL new_m,zu_m,zdum(ijb_u:ije_u,llm)
    40       REAL sigu(ijb_u:ije_u),dxq(ijb_u:ije_u,llm),dxqu(ijb_u:ije_u)
    41       REAL zz(ijb_u:ije_u)
    42       REAL adxqu(ijb_u:ije_u),dxqmax(ijb_u:ije_u,llm)
    43       REAL u_mq(ijb_u:ije_u,llm)
    44 
    45       REAL Ratio(ijb_u:ije_u,llm,nqtot) ! CRisi
    46       INTEGER ifils,iq2 ! CRisi
    47 
    48       Logical extremum
    49 
    50       REAL      SSUM
    51       EXTERNAL  SSUM
    52 
    53       REAL z1,z2,z3
    54 
    55       INTEGER ijb,ije,ijb_x,ije_x
    56      
    57       !write(*,*) 'vlsplt 58: entree dans vlx_loc, iq,ijb_x=',
    58 !    &   iq,ijb_x
    59 c   calcul de la pente a droite et a gauche de la maille
    60 
    61       ijb=ijb_x
    62       ije=ije_x
    63        
    64       if (pole_nord.and.ijb==1) ijb=ijb+iip1
    65       if (pole_sud.and.ije==ip1jmp1)  ije=ije-iip1
    66          
    67       IF (pente_max.gt.-1.e-5) THEN
    68 c      IF (pente_max.gt.10) THEN
    69 
    70 c   calcul des pentes avec limitation, Van Leer scheme I:
    71 c   -----------------------------------------------------
    72       ! on a besoin de q entre ijb et ije
    73 c   calcul de la pente aux points u
    74 c$OMP DO SCHEDULE(STATIC,OMP_CHUNK)         
    75          DO l = 1, llm
    76            
    77             DO ij=ijb,ije-1
    78                dxqu(ij)=q(ij+1,l,iq)-q(ij,l,iq)
    79 c              IF(u_m(ij,l).lt.0.) stop'limx n admet pas les U<0'
    80 c              sigu(ij)=u_m(ij,l)/masse(ij,l,iq)
    81             ENDDO
    82             DO ij=ijb+iip1-1,ije,iip1
    83                dxqu(ij)=dxqu(ij-iim)
    84 c              sigu(ij)=sigu(ij-iim)
    85             ENDDO
    86 
    87             DO ij=ijb,ije
    88                adxqu(ij)=abs(dxqu(ij))
    89             ENDDO
    90 
    91 c   calcul de la pente maximum dans la maille en valeur absolue
    92 
    93             DO ij=ijb+1,ije
    94                dxqmax(ij,l)=pente_max*
    95      ,      min(adxqu(ij-1),adxqu(ij))
    96 c limitation subtile
    97 c    ,      min(adxqu(ij-1)/sigu(ij-1),adxqu(ij)/(1.-sigu(ij)))
    98          
    99 
    100             ENDDO
    101 
    102             DO ij=ijb+iip1-1,ije,iip1
    103                dxqmax(ij-iim,l)=dxqmax(ij,l)
    104             ENDDO
    105 
    106             DO ij=ijb+1,ije
     4RECURSIVE SUBROUTINE vlx_loc(q,pente_max,masse,u_m,ijb_x,ije_x,iq)
     5
     6  ! Auteurs:   P.Le Van, F.Hourdin, F.Forget
     7  !
     8  !    ********************************************************************
     9  ! Shema  d'advection " pseudo amont " .
     10  !    ********************************************************************
     11  ! nq,iq,q,pbaru,pbarv,w sont des arguments d'entree  pour le s-pg ....
     12  !
     13  !
     14  !   --------------------------------------------------------------------
     15  USE parallel_lmdz
     16  USE infotrac, ONLY : nqtot,tracers, & ! CRisi                 &
     17        min_qParent,min_qMass,min_ratio ! MVals et CRisi
     18  IMPLICIT NONE
     19  !
     20  include "dimensions.h"
     21  include "paramet.h"
     22  include "iniprint.h"
     23  !
     24  !
     25  !   Arguments:
     26  !   ----------
     27  REAL :: masse(ijb_u:ije_u,llm,nqtot),pente_max
     28  REAL :: u_m( ijb_u:ije_u,llm),pbarv( iip1,jjb_v:jje_v,llm)
     29  REAL :: q(ijb_u:ije_u,llm,nqtot) ! CRisi: ajout dimension nqtot
     30  REAL :: w(ijb_u:ije_u,llm)
     31  INTEGER :: iq ! CRisi
     32  !
     33  !  Local
     34  !   ---------
     35  !
     36  INTEGER :: ij,l,j,i,iju,ijq,indu(ijnb_u),niju
     37  INTEGER :: n0,iadvplus(ijb_u:ije_u,llm),nl(llm)
     38  !
     39  REAL :: new_m,zu_m,zdum(ijb_u:ije_u,llm)
     40  REAL :: sigu(ijb_u:ije_u),dxq(ijb_u:ije_u,llm),dxqu(ijb_u:ije_u)
     41  REAL :: zz(ijb_u:ije_u)
     42  REAL :: adxqu(ijb_u:ije_u),dxqmax(ijb_u:ije_u,llm)
     43  REAL :: u_mq(ijb_u:ije_u,llm)
     44
     45  REAL :: Ratio(ijb_u:ije_u,llm,nqtot) ! CRisi
     46  INTEGER :: ifils,iq2 ! CRisi
     47
     48  Logical :: extremum
     49
     50  REAL :: SSUM
     51  EXTERNAL  SSUM
     52
     53  REAL :: z1,z2,z3
     54
     55  INTEGER :: ijb,ije,ijb_x,ije_x
     56
     57  ! !write(*,*) 'vlsplt 58: entree dans vlx_loc, iq,ijb_x=',
     58  ! &   iq,ijb_x
     59  !   calcul de la pente a droite et a gauche de la maille
     60
     61  ijb=ijb_x
     62  ije=ije_x
     63
     64  if (pole_nord.and.ijb==1) ijb=ijb+iip1
     65  if (pole_sud.and.ije==ip1jmp1)  ije=ije-iip1
     66
     67  IF (pente_max.gt.-1.e-5) THEN
     68    ! IF (pente_max.gt.10) THEN
     69
     70  !   calcul des pentes avec limitation, Van Leer scheme I:
     71  !   -----------------------------------------------------
     72  ! ! on a besoin de q entre ijb et ije
     73  !   calcul de la pente aux points u
     74!$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
     75     DO l = 1, llm
     76
     77        DO ij=ijb,ije-1
     78           dxqu(ij)=q(ij+1,l,iq)-q(ij,l,iq)
     79           ! IF(u_m(ij,l).lt.0.) stop'limx n admet pas les U<0'
     80           ! sigu(ij)=u_m(ij,l)/masse(ij,l,iq)
     81        ENDDO
     82        DO ij=ijb+iip1-1,ije,iip1
     83           dxqu(ij)=dxqu(ij-iim)
     84           ! sigu(ij)=sigu(ij-iim)
     85        ENDDO
     86
     87        DO ij=ijb,ije
     88           adxqu(ij)=abs(dxqu(ij))
     89        ENDDO
     90
     91  !   calcul de la pente maximum dans la maille en valeur absolue
     92
     93        DO ij=ijb+1,ije
     94           dxqmax(ij,l)=pente_max* &
     95                 min(adxqu(ij-1),adxqu(ij))
     96  ! limitation subtile
     97  !    ,      min(adxqu(ij-1)/sigu(ij-1),adxqu(ij)/(1.-sigu(ij)))
     98
     99
     100        ENDDO
     101
     102        DO ij=ijb+iip1-1,ije,iip1
     103           dxqmax(ij-iim,l)=dxqmax(ij,l)
     104        ENDDO
     105
     106        DO ij=ijb+1,ije
    107107#ifdef CRAY
    108                dxq(ij,l)=
    109      ,         cvmgp(dxqu(ij-1)+dxqu(ij),0.,dxqu(ij-1)*dxqu(ij))
     108           dxq(ij,l)= &
     109                 cvmgp(dxqu(ij-1)+dxqu(ij),0.,dxqu(ij-1)*dxqu(ij))
    110110#else
    111                IF(dxqu(ij-1)*dxqu(ij).gt.0) THEN
    112                   dxq(ij,l)=dxqu(ij-1)+dxqu(ij)
    113                ELSE
    114 c   extremum local
    115                   dxq(ij,l)=0.
    116                ENDIF
     111           IF(dxqu(ij-1)*dxqu(ij).gt.0) THEN
     112              dxq(ij,l)=dxqu(ij-1)+dxqu(ij)
     113           ELSE
     114  !   extremum local
     115              dxq(ij,l)=0.
     116           ENDIF
    117117#endif
    118                dxq(ij,l)=0.5*dxq(ij,l)
    119                dxq(ij,l)=
    120      ,         sign(min(abs(dxq(ij,l)),dxqmax(ij,l)),dxq(ij,l))
    121             ENDDO
    122 
    123          ENDDO ! l=1,llm
    124 c$OMP END DO NOWAIT
    125 c       print*,'Ok calcul des pentes'
    126 
    127       ELSE ! (pente_max.lt.-1.e-5)
    128 
    129 c   Pentes produits:
    130 c   ----------------
    131 c$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
    132          DO l = 1, llm
    133             DO ij=ijb,ije-1
    134                dxqu(ij)=q(ij+1,l,iq)-q(ij,l,iq)
    135             ENDDO
    136             DO ij=ijb+iip1-1,ije,iip1
    137                dxqu(ij)=dxqu(ij-iim)
    138             ENDDO
    139 
    140             DO ij=ijb+1,ije
    141                zz(ij)=dxqu(ij-1)*dxqu(ij)
    142                zz(ij)=zz(ij)+zz(ij)
    143                IF(zz(ij).gt.0) THEN
    144                   dxq(ij,l)=zz(ij)/(dxqu(ij-1)+dxqu(ij))
    145                ELSE
    146 c   extremum local
    147                   dxq(ij,l)=0.
    148                ENDIF
    149             ENDDO
    150 
    151          ENDDO
    152 c$OMP END DO NOWAIT
    153       ENDIF ! (pente_max.lt.-1.e-5)
    154 
    155       !write(*,*) 'vlx 156: iq,ijb_x=',iq,ijb_x
    156 
    157 c   bouclage de la pente en iip1:
    158 c   -----------------------------
    159 c$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
    160       DO l=1,llm
    161          DO ij=ijb+iip1-1,ije,iip1
    162             dxq(ij-iim,l)=dxq(ij,l)
    163          ENDDO
    164          DO ij=ijb,ije
    165             iadvplus(ij,l)=0
    166          ENDDO
    167 
    168       ENDDO
    169 c$OMP END DO NOWAIT
    170 c        print*,'Bouclage en iip1'
    171 
    172 c   calcul des flux a gauche et a droite
     118           dxq(ij,l)=0.5*dxq(ij,l)
     119           dxq(ij,l)= &
     120                 sign(min(abs(dxq(ij,l)),dxqmax(ij,l)),dxq(ij,l))
     121        ENDDO
     122
     123     ENDDO ! l=1,llm
     124!$OMP END DO NOWAIT
     125  ! print*,'Ok calcul des pentes'
     126
     127  ELSE ! (pente_max.lt.-1.e-5)
     128
     129  !   Pentes produits:
     130  !   ----------------
     131!$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
     132     DO l = 1, llm
     133        DO ij=ijb,ije-1
     134           dxqu(ij)=q(ij+1,l,iq)-q(ij,l,iq)
     135        ENDDO
     136        DO ij=ijb+iip1-1,ije,iip1
     137           dxqu(ij)=dxqu(ij-iim)
     138        ENDDO
     139
     140        DO ij=ijb+1,ije
     141           zz(ij)=dxqu(ij-1)*dxqu(ij)
     142           zz(ij)=zz(ij)+zz(ij)
     143           IF(zz(ij).gt.0) THEN
     144              dxq(ij,l)=zz(ij)/(dxqu(ij-1)+dxqu(ij))
     145           ELSE
     146  !   extremum local
     147              dxq(ij,l)=0.
     148           ENDIF
     149        ENDDO
     150
     151     ENDDO
     152!$OMP END DO NOWAIT
     153  ENDIF ! (pente_max.lt.-1.e-5)
     154
     155  ! !write(*,*) 'vlx 156: iq,ijb_x=',iq,ijb_x
     156
     157  !   bouclage de la pente en iip1:
     158  !   -----------------------------
     159!$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
     160  DO l=1,llm
     161     DO ij=ijb+iip1-1,ije,iip1
     162        dxq(ij-iim,l)=dxq(ij,l)
     163     ENDDO
     164     DO ij=ijb,ije
     165        iadvplus(ij,l)=0
     166     ENDDO
     167
     168  ENDDO
     169!$OMP END DO NOWAIT
     170   ! print*,'Bouclage en iip1'
     171
     172  !   calcul des flux a gauche et a droite
    173173
    174174#ifdef CRAY
    175 c$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
    176       DO l=1,llm
    177        DO ij=ijb,ije-1
    178           zdum(ij,l)=cvmgp(1.-u_m(ij,l)/masse(ij,l,iq),
    179      ,                     1.+u_m(ij,l)/masse(ij+1,l,iq),
    180      ,                     u_m(ij,l,iq))
    181           zdum(ij,l)=0.5*zdum(ij,l)
    182           u_mq(ij,l)=cvmgp(
    183      ,                q(ij,l,iq)+zdum(ij,l)*dxq(ij,l),
    184      ,                q(ij+1,l,iq)-zdum(ij,l)*dxq(ij+1,l),
    185      ,                u_m(ij,l))
    186           u_mq(ij,l)=u_m(ij,l)*u_mq(ij,l)
    187        ENDDO
    188       ENDDO
    189 c$OMP END DO NOWAIT
     175!$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
     176  DO l=1,llm
     177   DO ij=ijb,ije-1
     178      zdum(ij,l)=cvmgp(1.-u_m(ij,l)/masse(ij,l,iq), &
     179            1.+u_m(ij,l)/masse(ij+1,l,iq), &
     180            u_m(ij,l,iq))
     181      zdum(ij,l)=0.5*zdum(ij,l)
     182      u_mq(ij,l)=cvmgp( &
     183            q(ij,l,iq)+zdum(ij,l)*dxq(ij,l), &
     184            q(ij+1,l,iq)-zdum(ij,l)*dxq(ij+1,l), &
     185            u_m(ij,l))
     186      u_mq(ij,l)=u_m(ij,l)*u_mq(ij,l)
     187   ENDDO
     188  ENDDO
     189!$OMP END DO NOWAIT
    190190#else
    191 c   on cumule le flux correspondant a toutes les mailles dont la masse
    192 c   au travers de la paroi pENDant le pas de temps.
    193 c       print*,'Cumule ....'
    194 c$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
    195         ! on a besoin de masse entre ijb et ije
    196       DO l=1,llm
    197        DO ij=ijb,ije-1
    198 c       print*,'masse(',ij,')=',masse(ij,l,iq)
    199           IF (u_m(ij,l).gt.0.) THEN
    200              zdum(ij,l)=1.-u_m(ij,l)/masse(ij,l,iq)
    201              u_mq(ij,l)=u_m(ij,l)*(q(ij,l,iq)
    202      :           +0.5*zdum(ij,l)*dxq(ij,l))
    203           ELSE
    204              zdum(ij,l)=1.+u_m(ij,l)/masse(ij+1,l,iq)
    205              u_mq(ij,l)=u_m(ij,l)*(q(ij+1,l,iq)
    206      :           -0.5*zdum(ij,l)*dxq(ij+1,l))
    207           ENDIF
    208        ENDDO
    209       ENDDO
    210 c$OMP END DO NOWAIT
     191  !   on cumule le flux correspondant a toutes les mailles dont la masse
     192  !   au travers de la paroi pENDant le pas de temps.
     193  ! print*,'Cumule ....'
     194!$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
     195    ! ! on a besoin de masse entre ijb et ije
     196  DO l=1,llm
     197   DO ij=ijb,ije-1
     198  ! print*,'masse(',ij,')=',masse(ij,l,iq)
     199      IF (u_m(ij,l).gt.0.) THEN
     200         zdum(ij,l)=1.-u_m(ij,l)/masse(ij,l,iq)
     201         u_mq(ij,l)=u_m(ij,l)*(q(ij,l,iq) &
     202               +0.5*zdum(ij,l)*dxq(ij,l))
     203      ELSE
     204         zdum(ij,l)=1.+u_m(ij,l)/masse(ij+1,l,iq)
     205         u_mq(ij,l)=u_m(ij,l)*(q(ij+1,l,iq) &
     206               -0.5*zdum(ij,l)*dxq(ij+1,l))
     207      ENDIF
     208   ENDDO
     209  ENDDO
     210!$OMP END DO NOWAIT
    211211#endif
    212212
    213 c       go to 9999
    214 c   detection des points ou on advecte plus que la masse de la
    215 c   maille
    216 c$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
    217       DO l=1,llm
    218          DO ij=ijb,ije-1
    219             IF(zdum(ij,l).lt.0) THEN
    220                iadvplus(ij,l)=1
    221                u_mq(ij,l)=0.
    222             ENDIF
    223          ENDDO
    224       ENDDO
    225 c$OMP END DO NOWAIT
    226 c       print*,'Ok test 1'
    227 
    228 c$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
    229       DO l=1,llm
    230        DO ij=ijb+iip1-1,ije,iip1
    231           iadvplus(ij,l)=iadvplus(ij-iim,l)
    232        ENDDO
    233       ENDDO
    234 c$OMP END DO NOWAIT
    235 c        print*,'Ok test 2'
    236        
    237 
    238 c   traitement special pour le cas ou on advecte en longitude plus que le
    239 c   contenu de la maille.
    240 c   cette partie est mal vectorisee.
    241 
    242 c  calcul du nombre de maille sur lequel on advecte plus que la maille.
    243 
    244       n0=0
    245 c$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
    246       DO l=1,llm
    247          nl(l)=0
    248          DO ij=ijb,ije
    249             nl(l)=nl(l)+iadvplus(ij,l)
    250          ENDDO
    251          n0=n0+nl(l)
    252       ENDDO
    253 c$OMP END DO NOWAIT
    254 cym      IF(n0.gt.1) THEN
    255 cym      IF(n0.gt.0) THEN
    256 
    257 c      PRINT*,'Nombre de points pour lesquels on advect plus que le'
    258 c     &       ,'contenu de la maille : ',n0
    259 c$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
    260 
    261 
    262          DO l=1,llm
    263             IF(nl(l).gt.0) THEN
    264                iju=0
    265 c   indicage des mailles concernees par le traitement special
    266                DO ij=ijb,ije
    267                   IF(iadvplus(ij,l).eq.1.and.mod(ij,iip1).ne.0) THEN
    268                      iju=iju+1
    269                      indu(iju)=ij
    270                   ENDIF
    271                ENDDO
    272                niju=iju
    273                !PRINT*,'vlx 278, niju,nl',niju,nl(l)
    274 
    275 c  traitement des mailles
    276                DO iju=1,niju
    277                   ij=indu(iju)
    278                   j=(ij-1)/iip1+1
    279                   zu_m=u_m(ij,l)
    280                   u_mq(ij,l)=0.
    281                   IF(zu_m.gt.0.) THEN
    282                      ijq=ij
    283                      i=ijq-(j-1)*iip1
    284 c   accumulation pour les mailles completements advectees
    285                      do while(zu_m.gt.masse(ijq,l,iq))
    286                         u_mq(ij,l)=u_mq(ij,l)
    287      &                          +q(ijq,l,iq)*masse(ijq,l,iq)
    288                         zu_m=zu_m-masse(ijq,l,iq)
    289                         i=mod(i-2+iim,iim)+1
    290                         ijq=(j-1)*iip1+i
    291                      ENDDO
    292 c   ajout de la maille non completement advectee
    293                      u_mq(ij,l)=u_mq(ij,l)+zu_m*
    294      &               (q(ijq,l,iq)+0.5*
    295      &               (1.-zu_m/masse(ijq,l,iq))*dxq(ijq,l))
    296                   ELSE
    297                      ijq=ij+1
    298                      i=ijq-(j-1)*iip1
    299 c   accumulation pour les mailles completements advectees
    300                      do while(-zu_m.gt.masse(ijq,l,iq))
    301                         u_mq(ij,l)=u_mq(ij,l)-q(ijq,l,iq)
    302      &                           *masse(ijq,l,iq)
    303                         zu_m=zu_m+masse(ijq,l,iq)
    304                         i=mod(i,iim)+1
    305                         ijq=(j-1)*iip1+i
    306                      ENDDO
    307 c   ajout de la maille non completement advectee
    308                      u_mq(ij,l)=u_mq(ij,l)+zu_m*(q(ijq,l,iq)-
    309      &               0.5*(1.+zu_m/masse(ijq,l,iq))*dxq(ijq,l))
    310                   ENDIF
    311                ENDDO
    312             ENDIF
    313          ENDDO
    314 c$OMP END DO NOWAIT
    315 cym      ENDIF  ! n0.gt.0
    316 9999    continue
    317 
    318 c   bouclage en latitude
    319 c       print*,'Avant bouclage en latitude'
    320 c$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
    321       DO l=1,llm
    322         DO ij=ijb+iip1-1,ije,iip1
    323            u_mq(ij,l)=u_mq(ij-iim,l)
    324         ENDDO
    325       ENDDO
    326 c$OMP END DO NOWAIT
    327 
    328 ! CRisi: appel récursif de l'advection sur les fils.
    329 ! Il faut faire ça avant d'avoir mis à jour q et masse
    330 
    331       do ifils=1,tracers(iq)%nqDescen
    332         ! attention: comme Ratio est utilisé comme q dans l'appel
    333         ! recursif, il doit contenir à lui seul tous les indices de tous
    334         ! les descendants!
    335         iq2=tracers(iq)%iqDescen(ifils)
    336 c$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
    337         DO l=1,llm
    338           DO ij=ijb,ije
    339             ! On a besoin de q et masse seulement entre ijb et ije. On ne
    340             ! les calcule donc que de ijb à ije
    341             !MVals: veiller a ce qu'on n'ait pas de denominateur nul
    342             masse(ij,l,iq2)=max(masse(ij,l,iq)*q(ij,l,iq),min_qMass)
    343             if (q(ij,l,iq).gt.min_qParent) then ! modif 13 nov 2020
    344               Ratio(ij,l,iq2)=q(ij,l,iq2)/q(ij,l,iq)
    345             else
    346               Ratio(ij,l,iq2)=min_ratio
    347             endif
    348           enddo   
    349         enddo
    350 c$OMP END DO NOWAIT
    351       enddo !do ifils=1,tracers(iq)%nqDescen
    352       do ifils=1,tracers(iq)%nqChildren
    353         iq2=tracers(iq)%iqDescen(ifils)
    354         call vlx_loc(Ratio,pente_max,masse,u_mq,ijb_x,ije_x,iq2)
     213  ! go to 9999
     214  !   detection des points ou on advecte plus que la masse de la
     215  !   maille
     216!$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
     217  DO l=1,llm
     218     DO ij=ijb,ije-1
     219        IF(zdum(ij,l).lt.0) THEN
     220           iadvplus(ij,l)=1
     221           u_mq(ij,l)=0.
     222        ENDIF
     223     ENDDO
     224  ENDDO
     225!$OMP END DO NOWAIT
     226  ! print*,'Ok test 1'
     227
     228!$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
     229  DO l=1,llm
     230   DO ij=ijb+iip1-1,ije,iip1
     231      iadvplus(ij,l)=iadvplus(ij-iim,l)
     232   ENDDO
     233  ENDDO
     234!$OMP END DO NOWAIT
     235   ! print*,'Ok test 2'
     236
     237
     238  !   traitement special pour le cas ou on advecte en longitude plus que le
     239  !   contenu de la maille.
     240  !   cette partie est mal vectorisee.
     241
     242  !  calcul du nombre de maille sur lequel on advecte plus que la maille.
     243
     244  n0=0
     245!$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
     246  DO l=1,llm
     247     nl(l)=0
     248     DO ij=ijb,ije
     249        nl(l)=nl(l)+iadvplus(ij,l)
     250     ENDDO
     251     n0=n0+nl(l)
     252  ENDDO
     253!$OMP END DO NOWAIT
     254  !ym      IF(n0.gt.1) THEN
     255  !ym      IF(n0.gt.0) THEN
     256
     257   ! PRINT*,'Nombre de points pour lesquels on advect plus que le'
     258  ! &       ,'contenu de la maille : ',n0
     259!$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
     260
     261
     262     DO l=1,llm
     263        IF(nl(l).gt.0) THEN
     264           iju=0
     265  !   indicage des mailles concernees par le traitement special
     266           DO ij=ijb,ije
     267              IF(iadvplus(ij,l).eq.1.and.mod(ij,iip1).ne.0) THEN
     268                 iju=iju+1
     269                 indu(iju)=ij
     270              ENDIF
     271           ENDDO
     272           niju=iju
     273           ! !PRINT*,'vlx 278, niju,nl',niju,nl(l)
     274
     275  !  traitement des mailles
     276           DO iju=1,niju
     277              ij=indu(iju)
     278              j=(ij-1)/iip1+1
     279              zu_m=u_m(ij,l)
     280              u_mq(ij,l)=0.
     281              IF(zu_m.gt.0.) THEN
     282                 ijq=ij
     283                 i=ijq-(j-1)*iip1
     284  !   accumulation pour les mailles completements advectees
     285                 do while(zu_m.gt.masse(ijq,l,iq))
     286                    u_mq(ij,l)=u_mq(ij,l) &
     287                          +q(ijq,l,iq)*masse(ijq,l,iq)
     288                    zu_m=zu_m-masse(ijq,l,iq)
     289                    i=mod(i-2+iim,iim)+1
     290                    ijq=(j-1)*iip1+i
     291                 ENDDO
     292  !   ajout de la maille non completement advectee
     293                 u_mq(ij,l)=u_mq(ij,l)+zu_m* &
     294                       (q(ijq,l,iq)+0.5* &
     295                       (1.-zu_m/masse(ijq,l,iq))*dxq(ijq,l))
     296              ELSE
     297                 ijq=ij+1
     298                 i=ijq-(j-1)*iip1
     299  !   accumulation pour les mailles completements advectees
     300                 do while(-zu_m.gt.masse(ijq,l,iq))
     301                    u_mq(ij,l)=u_mq(ij,l)-q(ijq,l,iq) &
     302                          *masse(ijq,l,iq)
     303                    zu_m=zu_m+masse(ijq,l,iq)
     304                    i=mod(i,iim)+1
     305                    ijq=(j-1)*iip1+i
     306                 ENDDO
     307  !   ajout de la maille non completement advectee
     308                 u_mq(ij,l)=u_mq(ij,l)+zu_m*(q(ijq,l,iq)- &
     309                       0.5*(1.+zu_m/masse(ijq,l,iq))*dxq(ijq,l))
     310              ENDIF
     311           ENDDO
     312        ENDIF
     313     ENDDO
     314!$OMP END DO NOWAIT
     315  !ym      ENDIF  ! n0.gt.0
     3169999   continue
     317
     318  !   bouclage en latitude
     319  ! print*,'Avant bouclage en latitude'
     320!$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
     321  DO l=1,llm
     322    DO ij=ijb+iip1-1,ije,iip1
     323       u_mq(ij,l)=u_mq(ij-iim,l)
     324    ENDDO
     325  ENDDO
     326!$OMP END DO NOWAIT
     327
     328  ! CRisi: appel récursif de l'advection sur les fils.
     329  ! Il faut faire ça avant d'avoir mis à jour q et masse
     330
     331  do ifils=1,tracers(iq)%nqDescen
     332    ! ! attention: comme Ratio est utilisé comme q dans l'appel
     333    ! ! recursif, il doit contenir à lui seul tous les indices de tous
     334    ! ! les descendants!
     335    iq2=tracers(iq)%iqDescen(ifils)
     336!$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
     337    DO l=1,llm
     338      DO ij=ijb,ije
     339        ! ! On a besoin de q et masse seulement entre ijb et ije. On ne
     340        ! ! les calcule donc que de ijb à ije
     341        ! !MVals: veiller a ce qu'on n'ait pas de denominateur nul
     342        masse(ij,l,iq2)=max(masse(ij,l,iq)*q(ij,l,iq),min_qMass)
     343        if (q(ij,l,iq).gt.min_qParent) then ! modif 13 nov 2020
     344          Ratio(ij,l,iq2)=q(ij,l,iq2)/q(ij,l,iq)
     345        else
     346          Ratio(ij,l,iq2)=min_ratio
     347        endif
    355348      enddo
    356 ! end CRisi
    357 
    358 
    359 c   calcul des tENDances
    360 c$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
    361       DO l=1,llm
    362          DO ij=ijb+1,ije
    363             !MVals: veiller a ce qu'on n'ait pas de denominateur nul
    364             new_m=max(masse(ij,l,iq)+u_m(ij-1,l)-u_m(ij,l),min_qMass)
    365             q(ij,l,iq)=(q(ij,l,iq)*masse(ij,l,iq)+
    366      &        u_mq(ij-1,l)-u_mq(ij,l))
    367      &        /new_m
    368             masse(ij,l,iq)=new_m
    369          ENDDO
    370 c   ModIF Fred 22 03 96 correction d'un bug (les scopy ci-dessous)
    371          DO ij=ijb+iip1-1,ije,iip1
    372             q(ij-iim,l,iq)=q(ij,l,iq)
    373             masse(ij-iim,l,iq)=masse(ij,l,iq)
    374          ENDDO
    375       ENDDO
    376 c$OMP END DO NOWAIT
    377 
    378 ! retablir les fils en rapport de melange par rapport a l'air:
    379       ! On calcule q entre ijb+1 et ije -> on fait pareil pour ratio
    380       ! puis on boucle en longitude
    381       do ifils=1,tracers(iq)%nqDescen
    382         iq2=tracers(iq)%iqDescen(ifils)
    383 c$OMP DO SCHEDULE(STATIC,OMP_CHUNK)   
    384         DO l=1,llm
    385           DO ij=ijb+1,ije
    386             q(ij,l,iq2)=q(ij,l,iq)*Ratio(ij,l,iq2)           
    387           enddo
    388           DO ij=ijb+iip1-1,ije,iip1
    389             q(ij-iim,l,iq2)=q(ij,l,iq2)
    390           enddo
    391         enddo
    392 c$OMP END DO NOWAIT
     349    enddo
     350!$OMP END DO NOWAIT
     351  enddo !do ifils=1,tracers(iq)%nqDescen
     352  do ifils=1,tracers(iq)%nqChildren
     353    iq2=tracers(iq)%iqDescen(ifils)
     354    call vlx_loc(Ratio,pente_max,masse,u_mq,ijb_x,ije_x,iq2)
     355  enddo
     356  ! end CRisi
     357
     358
     359  !   calcul des tENDances
     360!$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
     361  DO l=1,llm
     362     DO ij=ijb+1,ije
     363        ! !MVals: veiller a ce qu'on n'ait pas de denominateur nul
     364        new_m=max(masse(ij,l,iq)+u_m(ij-1,l)-u_m(ij,l),min_qMass)
     365        q(ij,l,iq)=(q(ij,l,iq)*masse(ij,l,iq)+ &
     366              u_mq(ij-1,l)-u_mq(ij,l)) &
     367              /new_m
     368        masse(ij,l,iq)=new_m
     369     ENDDO
     370  !   ModIF Fred 22 03 96 correction d'un bug (les scopy ci-dessous)
     371     DO ij=ijb+iip1-1,ije,iip1
     372        q(ij-iim,l,iq)=q(ij,l,iq)
     373        masse(ij-iim,l,iq)=masse(ij,l,iq)
     374     ENDDO
     375  ENDDO
     376!$OMP END DO NOWAIT
     377
     378  ! retablir les fils en rapport de melange par rapport a l'air:
     379  ! ! On calcule q entre ijb+1 et ije -> on fait pareil pour ratio
     380  ! ! puis on boucle en longitude
     381  do ifils=1,tracers(iq)%nqDescen
     382    iq2=tracers(iq)%iqDescen(ifils)
     383!$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
     384    DO l=1,llm
     385      DO ij=ijb+1,ije
     386        q(ij,l,iq2)=q(ij,l,iq)*Ratio(ij,l,iq2)
    393387      enddo
    394 
    395       !write(*,*) 'vlsplt 399: iq,ijb_x=',iq,ijb_x
    396 c     CALL SCOPY((jjm-1)*llm,q(iip1+iip1,1),iip1,q(iip2,1),iip1)
    397 c     CALL SCOPY((jjm-1)*llm,masse(iip1+iip1,1),iip1,masse(iip2,1),iip1)
    398 
    399 
    400       RETURN
    401       END
    402 
    403 
    404       RECURSIVE SUBROUTINE vly_loc(q,pente_max,masse,masse_adv_v,iq)
    405 c
    406 c     Auteurs:   P.Le Van, F.Hourdin, F.Forget
    407 c
    408 c    ********************************************************************
    409 c     Shema  d'advection " pseudo amont " .
    410 c    ********************************************************************
    411 c     q,masse_adv_v,w sont des arguments d'entree  pour le s-pg ....
    412 c     dq               sont des arguments de sortie pour le s-pg ....
    413 c
    414 c
    415 c   --------------------------------------------------------------------
    416       USE parallel_lmdz
    417       USE infotrac, ONLY : nqtot,tracers, ! CRisi                 &
    418      &                     min_qParent,min_qMass,min_ratio ! MVals et CRisi   
    419       USE comconst_mod, ONLY: pi
    420       IMPLICIT NONE
    421 c
    422       include "dimensions.h"
    423       include "paramet.h"
    424       include "comgeom.h"
    425 c
    426 c
    427 c   Arguments:
    428 c   ----------
    429       REAL masse(ijb_u:ije_u,llm,nqtot),pente_max
    430       REAL masse_adv_v( ijb_v:ije_v,llm)
    431       REAL q(ijb_u:ije_u,llm,nqtot), dq( ijb_u:ije_u,llm)
    432       INTEGER iq ! CRisi
    433 c
    434 c      Local
    435 c   ---------
    436 c
    437       INTEGER i,ij,l
    438 c
    439       REAL airej2,airejjm,airescb(iim),airesch(iim)
    440       REAL dyq(ijb_u:ije_u,llm),dyqv(ijb_v:ije_v),zdvm(ijb_u:ije_u,llm)
    441       REAL adyqv(ijb_v:ije_v),dyqmax(ijb_u:ije_u)
    442       REAL qbyv(ijb_v:ije_v,llm)
    443 
    444       REAL qpns,qpsn,appn,apps,dyn1,dys1,dyn2,dys2,newmasse,fn,fs
    445 c     REAL newq,oldmasse
    446       Logical extremum,first,testcpu
    447       REAL temps0,temps1,temps2,temps3,temps4,temps5,second
    448       SAVE temps0,temps1,temps2,temps3,temps4,temps5
    449 c$OMP THREADPRIVATE(temps0,temps1,temps2,temps3,temps4,temps5)
    450       SAVE first,testcpu
    451 c$OMP THREADPRIVATE(first,testcpu)
    452 
    453       REAL convpn,convps,convmpn,convmps
    454       real massepn,masseps,qpn,qps
    455       REAL sinlon(iip1),sinlondlon(iip1)
    456       REAL coslon(iip1),coslondlon(iip1)
    457       SAVE sinlon,coslon,sinlondlon,coslondlon
    458 c$OMP THREADPRIVATE(sinlon,coslon,sinlondlon,coslondlon)
    459       SAVE airej2,airejjm
    460 c$OMP THREADPRIVATE(airej2,airejjm)
    461 
    462       REAL Ratio(ijb_u:ije_u,llm,nqtot) ! CRisi
    463       INTEGER ifils,iq2 ! CRisi
    464 c
    465 c
    466       REAL      SSUM
    467       EXTERNAL  SSUM
    468 
    469       DATA first,testcpu/.true.,.false./
    470       DATA temps0,temps1,temps2,temps3,temps4,temps5/0.,0.,0.,0.,0.,0./
    471       INTEGER ijb,ije
    472       INTEGER ijbm,ijem
    473 
    474       ijb=ij_begin-2*iip1
    475       ije=ij_end+2*iip1 
    476       if (pole_nord) ijb=ij_begin
    477       if (pole_sud)  ije=ij_end
    478 
    479       IF(first) THEN
    480          PRINT*,'Shema  Amont nouveau  appele dans  Vanleer   '
    481          first=.false.
    482          do i=2,iip1
    483             coslon(i)=cos(rlonv(i))
    484             sinlon(i)=sin(rlonv(i))
    485             coslondlon(i)=coslon(i)*(rlonu(i)-rlonu(i-1))/pi
    486             sinlondlon(i)=sinlon(i)*(rlonu(i)-rlonu(i-1))/pi
    487          ENDDO
    488          coslon(1)=coslon(iip1)
    489          coslondlon(1)=coslondlon(iip1)
    490          sinlon(1)=sinlon(iip1)
    491          sinlondlon(1)=sinlondlon(iip1)
    492          airej2 = SSUM( iim, aire(iip2), 1 )
    493          airejjm= SSUM( iim, aire(ip1jm -iim), 1 )
     388      DO ij=ijb+iip1-1,ije,iip1
     389        q(ij-iim,l,iq2)=q(ij,l,iq2)
     390      enddo
     391    enddo
     392!$OMP END DO NOWAIT
     393  enddo
     394
     395  ! !write(*,*) 'vlsplt 399: iq,ijb_x=',iq,ijb_x
     396  ! CALL SCOPY((jjm-1)*llm,q(iip1+iip1,1),iip1,q(iip2,1),iip1)
     397  ! CALL SCOPY((jjm-1)*llm,masse(iip1+iip1,1),iip1,masse(iip2,1),iip1)
     398
     399
     400  RETURN
     401END SUBROUTINE vlx_loc
     402
     403
     404RECURSIVE SUBROUTINE vly_loc(q,pente_max,masse,masse_adv_v,iq)
     405  !
     406  ! Auteurs:   P.Le Van, F.Hourdin, F.Forget
     407  !
     408  !    ********************************************************************
     409  ! Shema  d'advection " pseudo amont " .
     410  !    ********************************************************************
     411  ! q,masse_adv_v,w sont des arguments d'entree  pour le s-pg ....
     412  ! dq         sont des arguments de sortie pour le s-pg ....
     413  !
     414  !
     415  !   --------------------------------------------------------------------
     416  USE parallel_lmdz
     417  USE infotrac, ONLY : nqtot,tracers, & ! CRisi                 &
     418        min_qParent,min_qMass,min_ratio ! MVals et CRisi
     419  USE comconst_mod, ONLY: pi
     420  IMPLICIT NONE
     421  !
     422  include "dimensions.h"
     423  include "paramet.h"
     424  include "comgeom.h"
     425  !
     426  !
     427  !   Arguments:
     428  !   ----------
     429  REAL :: masse(ijb_u:ije_u,llm,nqtot),pente_max
     430  REAL :: masse_adv_v( ijb_v:ije_v,llm)
     431  REAL :: q(ijb_u:ije_u,llm,nqtot), dq( ijb_u:ije_u,llm)
     432  INTEGER :: iq ! CRisi
     433  !
     434  !  Local
     435  !   ---------
     436  !
     437  INTEGER :: i,ij,l
     438  !
     439  REAL :: airej2,airejjm,airescb(iim),airesch(iim)
     440  REAL :: dyq(ijb_u:ije_u,llm),dyqv(ijb_v:ije_v),zdvm(ijb_u:ije_u,llm)
     441  REAL :: adyqv(ijb_v:ije_v),dyqmax(ijb_u:ije_u)
     442  REAL :: qbyv(ijb_v:ije_v,llm)
     443
     444  REAL :: qpns,qpsn,appn,apps,dyn1,dys1,dyn2,dys2,newmasse,fn,fs
     445  ! REAL newq,oldmasse
     446  Logical :: extremum,first,testcpu
     447  REAL :: temps0,temps1,temps2,temps3,temps4,temps5,second
     448  SAVE temps0,temps1,temps2,temps3,temps4,temps5
     449!$OMP THREADPRIVATE(temps0,temps1,temps2,temps3,temps4,temps5)
     450  SAVE first,testcpu
     451!$OMP THREADPRIVATE(first,testcpu)
     452
     453  REAL :: convpn,convps,convmpn,convmps
     454  real :: massepn,masseps,qpn,qps
     455  REAL :: sinlon(iip1),sinlondlon(iip1)
     456  REAL :: coslon(iip1),coslondlon(iip1)
     457  SAVE sinlon,coslon,sinlondlon,coslondlon
     458!$OMP THREADPRIVATE(sinlon,coslon,sinlondlon,coslondlon)
     459  SAVE airej2,airejjm
     460!$OMP THREADPRIVATE(airej2,airejjm)
     461
     462  REAL :: Ratio(ijb_u:ije_u,llm,nqtot) ! CRisi
     463  INTEGER :: ifils,iq2 ! CRisi
     464  !
     465  !
     466  REAL :: SSUM
     467  EXTERNAL  SSUM
     468
     469  DATA first,testcpu/.true.,.false./
     470  DATA temps0,temps1,temps2,temps3,temps4,temps5/0.,0.,0.,0.,0.,0./
     471  INTEGER :: ijb,ije
     472  INTEGER :: ijbm,ijem
     473
     474  ijb=ij_begin-2*iip1
     475  ije=ij_end+2*iip1
     476  if (pole_nord) ijb=ij_begin
     477  if (pole_sud)  ije=ij_end
     478
     479  IF(first) THEN
     480     PRINT*,'Shema  Amont nouveau  appele dans  Vanleer   '
     481     first=.false.
     482     do i=2,iip1
     483        coslon(i)=cos(rlonv(i))
     484        sinlon(i)=sin(rlonv(i))
     485        coslondlon(i)=coslon(i)*(rlonu(i)-rlonu(i-1))/pi
     486        sinlondlon(i)=sinlon(i)*(rlonu(i)-rlonu(i-1))/pi
     487     ENDDO
     488     coslon(1)=coslon(iip1)
     489     coslondlon(1)=coslondlon(iip1)
     490     sinlon(1)=sinlon(iip1)
     491     sinlondlon(1)=sinlondlon(iip1)
     492     airej2 = SSUM( iim, aire(iip2), 1 )
     493     airejjm= SSUM( iim, aire(ip1jm -iim), 1 )
     494  ENDIF
     495
     496  !
     497  ! PRINT*,'CALCUL EN LATITUDE'
     498
     499!$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
     500  DO l = 1, llm
     501  !
     502  !   --------------------------------
     503  !  CALCUL EN LATITUDE
     504  !   --------------------------------
     505
     506  !   On commence par calculer la valeur du traceur moyenne sur le premier cercle
     507  !   de latitude autour du pole (qpns pour le pole nord et qpsn pour
     508  !    le pole nord) qui sera utilisee pour evaluer les pentes au pole.
     509
     510  if (pole_nord) then
     511    DO i = 1, iim
     512      airescb(i) = aire(i+ iip1) * q(i+ iip1,l,iq)
     513    ENDDO
     514    qpns   = SSUM( iim,  airescb ,1 ) / airej2
     515  endif
     516
     517  if (pole_sud) then
     518    DO i = 1, iim
     519      airesch(i) = aire(i+ ip1jm- iip1) * q(i+ ip1jm- iip1,l,iq)
     520    ENDDO
     521    qpsn   = SSUM( iim,  airesch ,1 ) / airejjm
     522  endif
     523
     524  !   calcul des pentes aux points v
     525
     526  ijb=ij_begin-2*iip1
     527  ije=ij_end+iip1
     528  if (pole_nord) ijb=ij_begin
     529  if (pole_sud)  ije=ij_end-iip1
     530
     531  ! ! on a besoin de q entre ij_begin-2*iip1 et ij_end+2*iip1
     532  ! ! Si pole sud, entre ij_begin-2*iip1 et ij_end
     533  ! ! Si pole Nord, entre ij_begin et ij_end+2*iip1
     534  DO ij=ijb,ije
     535     dyqv(ij)=q(ij,l,iq)-q(ij+iip1,l,iq)
     536     adyqv(ij)=abs(dyqv(ij))
     537  ENDDO
     538
     539
     540  !   calcul des pentes aux points scalaires
     541  ijb=ij_begin-iip1
     542  ije=ij_end+iip1
     543  if (pole_nord) ijb=ij_begin+iip1
     544  if (pole_sud)  ije=ij_end-iip1
     545
     546  DO ij=ijb,ije
     547     dyq(ij,l)=.5*(dyqv(ij-iip1)+dyqv(ij))
     548     dyqmax(ij)=min(adyqv(ij-iip1),adyqv(ij))
     549     dyqmax(ij)=pente_max*dyqmax(ij)
     550  ENDDO
     551
     552  !   calcul des pentes aux poles
     553  IF (pole_nord) THEN
     554    DO ij=1,iip1
     555       dyq(ij,l)=qpns-q(ij+iip1,l,iq)
     556    ENDDO
     557
     558    dyn1=0.
     559    dyn2=0.
     560    DO ij=1,iim
     561      dyn1=dyn1+sinlondlon(ij)*dyq(ij,l)
     562      dyn2=dyn2+coslondlon(ij)*dyq(ij,l)
     563    ENDDO
     564    DO ij=1,iip1
     565      dyq(ij,l)=dyn1*sinlon(ij)+dyn2*coslon(ij)
     566    ENDDO
     567
     568    DO ij=1,iip1
     569     dyq(ij,l)=0.
     570    ENDDO
     571  ! ym tout cela ne sert pas a grand chose
     572  ENDIF
     573
     574  IF (pole_sud) THEN
     575
     576    DO ij=1,iip1
     577       dyq(ip1jm+ij,l)=q(ip1jm+ij-iip1,l,iq)-qpsn
     578    ENDDO
     579
     580    dys1=0.
     581    dys2=0.
     582
     583    DO ij=1,iim
     584      dys1=dys1+sinlondlon(ij)*dyq(ip1jm+ij,l)
     585      dys2=dys2+coslondlon(ij)*dyq(ip1jm+ij,l)
     586    ENDDO
     587
     588    DO ij=1,iip1
     589      dyq(ip1jm+ij,l)=dys1*sinlon(ij)+dys2*coslon(ij)
     590    ENDDO
     591
     592    DO ij=1,iip1
     593     dyq(ip1jm+ij,l)=0.
     594    ENDDO
     595  ! ym tout cela ne sert pas a grand chose
     596  ENDIF
     597
     598  !   filtrage de la derivee
     599
     600  !   calcul des pentes limites aux poles
     601  ! ym partie inutile
     602   ! goto 8888
     603   ! fn=1.
     604   ! fs=1.
     605   ! DO ij=1,iim
     606   !    IF(pente_max*adyqv(ij).lt.abs(dyq(ij,l))) THEN
     607   !       fn=min(pente_max*adyqv(ij)/abs(dyq(ij,l)),fn)
     608   !    ENDIF
     609   ! IF(pente_max*adyqv(ij+ip1jm-iip1).lt.abs(dyq(ij+ip1jm,l))) THEN
     610   !    fs=min(pente_max*adyqv(ij+ip1jm-iip1)/abs(dyq(ij+ip1jm,l)),fs)
     611   !    ENDIF
     612   ! ENDDO
     613   ! DO ij=1,iip1
     614   !    dyq(ij,l)=fn*dyq(ij,l)
     615   !    dyq(ip1jm+ij,l)=fs*dyq(ip1jm+ij,l)
     616   ! ENDDO
     617  ! 8888    continue
     618
     619
     620  !CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
     621  !  En memoire de dIFferents tests sur la
     622  !  limitation des pentes aux poles.
     623  !CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
     624  ! PRINT*,dyq(1)
     625  ! PRINT*,dyqv(iip1+1)
     626  ! appn=abs(dyq(1)/dyqv(iip1+1))
     627  ! PRINT*,dyq(ip1jm+1)
     628  ! PRINT*,dyqv(ip1jm-iip1+1)
     629  ! apps=abs(dyq(ip1jm+1)/dyqv(ip1jm-iip1+1))
     630  ! DO ij=2,iim
     631  !    appn=amax1(abs(dyq(ij)/dyqv(ij)),appn)
     632  !    apps=amax1(abs(dyq(ip1jm+ij)/dyqv(ip1jm-iip1+ij)),apps)
     633  ! ENDDO
     634  ! appn=min(pente_max/appn,1.)
     635  ! apps=min(pente_max/apps,1.)
     636  !
     637  !
     638  !   cas ou on a un extremum au pole
     639  !
     640  ! IF(dyqv(ismin(iim,dyqv,1))*dyqv(ismax(iim,dyqv,1)).le.0.)
     641  !    &   appn=0.
     642  ! IF(dyqv(ismax(iim,dyqv(ip1jm-iip1+1),1)+ip1jm-iip1+1)*
     643  !    &   dyqv(ismin(iim,dyqv(ip1jm-iip1+1),1)+ip1jm-iip1+1).le.0.)
     644  !    &   apps=0.
     645  !
     646  !   limitation des pentes aux poles
     647  ! DO ij=1,iip1
     648  !    dyq(ij)=appn*dyq(ij)
     649  !    dyq(ip1jm+ij)=apps*dyq(ip1jm+ij)
     650  ! ENDDO
     651  !
     652  !   test
     653  !  DO ij=1,iip1
     654  !     dyq(iip1+ij)=0.
     655  !     dyq(ip1jm+ij-iip1)=0.
     656  !  ENDDO
     657  !  DO ij=1,ip1jmp1
     658  !     dyq(ij)=dyq(ij)*cos(rlatu((ij-1)/iip1+1))
     659  !  ENDDO
     660  !
     661  ! changement 10 07 96
     662  ! IF(dyqv(ismin(iim,dyqv,1))*dyqv(ismax(iim,dyqv,1)).le.0.)
     663  !    &   THEN
     664  !    DO ij=1,iip1
     665  !       dyqmax(ij)=0.
     666  !    ENDDO
     667  ! ELSE
     668  !    DO ij=1,iip1
     669  !       dyqmax(ij)=pente_max*abs(dyqv(ij))
     670  !    ENDDO
     671  ! ENDIF
     672  !
     673  ! IF(dyqv(ismax(iim,dyqv(ip1jm-iip1+1),1)+ip1jm-iip1+1)*
     674  !    & dyqv(ismin(iim,dyqv(ip1jm-iip1+1),1)+ip1jm-iip1+1).le.0.)
     675  !    &THEN
     676  !    DO ij=ip1jm+1,ip1jmp1
     677  !       dyqmax(ij)=0.
     678  !    ENDDO
     679  ! ELSE
     680  !    DO ij=ip1jm+1,ip1jmp1
     681  !       dyqmax(ij)=pente_max*abs(dyqv(ij-iip1))
     682  !    ENDDO
     683  ! ENDIF
     684  !   fin changement 10 07 96
     685  !CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
     686
     687  !   calcul des pentes limitees
     688  ijb=ij_begin-iip1
     689  ije=ij_end+iip1
     690  if (pole_nord) ijb=ij_begin+iip1
     691  if (pole_sud)  ije=ij_end-iip1
     692
     693  DO ij=ijb,ije
     694     IF(dyqv(ij)*dyqv(ij-iip1).gt.0.) THEN
     695        dyq(ij,l)=sign(min(abs(dyq(ij,l)),dyqmax(ij)),dyq(ij,l))
     696     ELSE
     697        dyq(ij,l)=0.
     698     ENDIF
     699  ENDDO
     700
     701  ENDDO
     702!$OMP END DO NOWAIT
     703
     704  ijb=ij_begin-iip1
     705  ije=ij_end
     706  if (pole_nord) ijb=ij_begin
     707  if (pole_sud)  ije=ij_end-iip1
     708
     709!$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
     710  DO l=1,llm
     711   DO ij=ijb,ije
     712      IF(masse_adv_v(ij,l).gt.0) THEN
     713          qbyv(ij,l)=q(ij+iip1,l,iq)+dyq(ij+iip1,l)* &
     714                0.5*(1.-masse_adv_v(ij,l) &
     715                /masse(ij+iip1,l,iq))
     716      ELSE
     717          qbyv(ij,l)=q(ij,l,iq)-dyq(ij,l)* &
     718                0.5*(1.+masse_adv_v(ij,l)/masse(ij,l,iq))
    494719      ENDIF
    495 
    496 c
    497 c       PRINT*,'CALCUL EN LATITUDE'
    498 
    499 c$OMP DO SCHEDULE(STATIC,OMP_CHUNK)     
    500       DO l = 1, llm
    501 c
    502 c   --------------------------------
    503 c      CALCUL EN LATITUDE
    504 c   --------------------------------
    505 
    506 c   On commence par calculer la valeur du traceur moyenne sur le premier cercle
    507 c   de latitude autour du pole (qpns pour le pole nord et qpsn pour
    508 c    le pole nord) qui sera utilisee pour evaluer les pentes au pole.
    509      
    510       if (pole_nord) then
    511         DO i = 1, iim
    512           airescb(i) = aire(i+ iip1) * q(i+ iip1,l,iq)
    513         ENDDO
    514         qpns   = SSUM( iim,  airescb ,1 ) / airej2
    515       endif
    516      
    517       if (pole_sud) then
    518         DO i = 1, iim
    519           airesch(i) = aire(i+ ip1jm- iip1) * q(i+ ip1jm- iip1,l,iq)
    520         ENDDO
    521         qpsn   = SSUM( iim,  airesch ,1 ) / airejjm
    522       endif
    523      
    524 c   calcul des pentes aux points v
    525 
    526       ijb=ij_begin-2*iip1
    527       ije=ij_end+iip1
    528       if (pole_nord) ijb=ij_begin
    529       if (pole_sud)  ije=ij_end-iip1
    530      
    531       ! on a besoin de q entre ij_begin-2*iip1 et ij_end+2*iip1
    532       ! Si pole sud, entre ij_begin-2*iip1 et ij_end
    533       ! Si pole Nord, entre ij_begin et ij_end+2*iip1
     720      qbyv(ij,l)=masse_adv_v(ij,l)*qbyv(ij,l)
     721   ENDDO
     722  ENDDO
     723!$OMP END DO NOWAIT
     724
     725  ! CRisi: appel récursif de l'advection sur les fils.
     726  ! Il faut faire ça avant d'avoir mis à jour q et masse
     727  ! write(*,*)'vly 689: iq,nqChildren(iq)=',iq,tracers(iq)%nqChildren
     728
     729  ijb=ij_begin-2*iip1
     730  ije=ij_end+2*iip1
     731  ijbm=ij_begin-iip1
     732  ijem=ij_end+iip1
     733  if (pole_nord) ijb=ij_begin
     734  if (pole_sud)  ije=ij_end
     735  if (pole_nord) ijbm=ij_begin
     736  if (pole_sud)  ijem=ij_end
     737
     738  do ifils=1,tracers(iq)%nqDescen
     739    iq2=tracers(iq)%iqDescen(ifils)
     740!$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
     741    DO l=1,llm
     742    ! ! modif des bornes: CRisi 16 nov 2020
     743    ! ! d'abord masse avec bornes corrigées
     744      DO ij=ijbm,ijem
     745      ! !MVals: veiller a ce qu'on n'ait pas de denominateur nul
     746        masse(ij,l,iq2)=max(masse(ij,l,iq)*q(ij,l,iq),min_qMass)
     747      enddo
     748
     749      ! ! ensuite Ratio avec anciennes bornes
    534750      DO ij=ijb,ije
    535          dyqv(ij)=q(ij,l,iq)-q(ij+iip1,l,iq)
    536          adyqv(ij)=abs(dyqv(ij))
    537       ENDDO
    538  
    539 
    540 c   calcul des pentes aux points scalaires
    541       ijb=ij_begin-iip1
    542       ije=ij_end+iip1
    543       if (pole_nord) ijb=ij_begin+iip1
    544       if (pole_sud)  ije=ij_end-iip1
    545      
     751      ! !MVals: veiller a ce qu'on n'ait pas de denominateur nul
     752        if (q(ij,l,iq).gt.min_qParent) then ! modif 13 nov 2020
     753          Ratio(ij,l,iq2)=q(ij,l,iq2)/q(ij,l,iq)
     754        else
     755          Ratio(ij,l,iq2)=min_ratio
     756        endif
     757      enddo !DO ij=ijbm,ijem
     758    enddo !DO l=1,llm
     759!$OMP END DO NOWAIT
     760  enddo
     761
     762  do ifils=1,tracers(iq)%nqChildren
     763    iq2=tracers(iq)%iqDescen(ifils)
     764    call vly_loc(Ratio,pente_max,masse,qbyv,iq2)
     765  enddo
     766  ! end CRisi
     767
     768  ijb=ij_begin
     769  ije=ij_end
     770  if (pole_nord) ijb=ij_begin+iip1
     771  if (pole_sud)  ije=ij_end-iip1
     772
     773!$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
     774  DO l=1,llm
     775     DO ij=ijb,ije
     776        newmasse=masse(ij,l,iq) &
     777              +masse_adv_v(ij,l)-masse_adv_v(ij-iip1,l)
     778
     779        q(ij,l,iq)=(q(ij,l,iq)*masse(ij,l,iq)+qbyv(ij,l) &
     780              -qbyv(ij-iip1,l))/newmasse
     781
     782        masse(ij,l,iq)=newmasse
     783
     784     ENDDO
     785
     786
     787  !.-. ancienne version
     788     ! convpn=SSUM(iim,qbyv(1,l),1)/apoln
     789     ! convmpn=ssum(iim,masse_adv_v(1,l),1)/apoln
     790     if (pole_nord) then
     791       convpn=SSUM(iim,qbyv(1,l),1)
     792       convmpn=ssum(iim,masse_adv_v(1,l),1)
     793       massepn=ssum(iim,masse(1,l,iq),1)
     794       qpn=0.
     795       do ij=1,iim
     796          qpn=qpn+masse(ij,l,iq)*q(ij,l,iq)
     797       enddo
     798       qpn=(qpn+convpn)/(massepn+convmpn)
     799       do ij=1,iip1
     800          q(ij,l,iq)=qpn
     801       enddo
     802     endif
     803
     804     ! convps=-SSUM(iim,qbyv(ip1jm-iim,l),1)/apols
     805     ! convmps=-ssum(iim,masse_adv_v(ip1jm-iim,l),1)/apols
     806
     807     if (pole_sud) then
     808
     809       convps=-SSUM(iim,qbyv(ip1jm-iim,l),1)
     810       convmps=-ssum(iim,masse_adv_v(ip1jm-iim,l),1)
     811       masseps=ssum(iim, masse(ip1jm+1,l,iq),1)
     812       qps=0.
     813       do ij = ip1jm+1,ip1jmp1-1
     814          qps=qps+masse(ij,l,iq)*q(ij,l,iq)
     815       enddo
     816       qps=(qps+convps)/(masseps+convmps)
     817       do ij=ip1jm+1,ip1jmp1
     818          q(ij,l,iq)=qps
     819       enddo
     820     endif
     821  !.-. fin ancienne version
     822
     823  !._. nouvelle version
     824     ! convpn=SSUM(iim,qbyv(1,l),1)
     825     ! convmpn=ssum(iim,masse_adv_v(1,l),1)
     826     ! oldmasse=ssum(iim,masse(1,l),1)
     827     ! newmasse=oldmasse+convmpn
     828     ! newq=(q(1,l)*oldmasse+convpn)/newmasse
     829     ! newmasse=newmasse/apoln
     830     ! DO ij = 1,iip1
     831     !    q(ij,l)=newq
     832     !    masse(ij,l,iq)=newmasse*aire(ij)
     833     ! ENDDO
     834     ! convps=-SSUM(iim,qbyv(ip1jm-iim,l),1)
     835     ! convmps=-ssum(iim,masse_adv_v(ip1jm-iim,l),1)
     836     ! oldmasse=ssum(iim,masse(ip1jm-iim,l),1)
     837     ! newmasse=oldmasse+convmps
     838     ! newq=(q(ip1jmp1,l)*oldmasse+convps)/newmasse
     839     ! newmasse=newmasse/apols
     840     ! DO ij = ip1jm+1,ip1jmp1
     841     !    q(ij,l)=newq
     842     !    masse(ij,l,iq)=newmasse*aire(ij)
     843     ! ENDDO
     844  !._. fin nouvelle version
     845  ENDDO
     846!$OMP END DO NOWAIT
     847
     848  ! retablir les fils en rapport de melange par rapport a l'air:
     849  ijb=ij_begin
     850  ije=ij_end
     851   ! if (pole_nord) ijb=ij_begin
     852   ! if (pole_sud)  ije=ij_end
     853
     854  do ifils=1,tracers(iq)%nqDescen
     855    iq2=tracers(iq)%iqDescen(ifils)
     856!$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
     857    DO l=1,llm
    546858      DO ij=ijb,ije
    547          dyq(ij,l)=.5*(dyqv(ij-iip1)+dyqv(ij))
    548          dyqmax(ij)=min(adyqv(ij-iip1),adyqv(ij))
    549          dyqmax(ij)=pente_max*dyqmax(ij)
    550       ENDDO
    551 
    552 c   calcul des pentes aux poles
    553       IF (pole_nord) THEN
    554         DO ij=1,iip1
    555            dyq(ij,l)=qpns-q(ij+iip1,l,iq)
    556         ENDDO
    557        
    558         dyn1=0.
    559         dyn2=0.
    560         DO ij=1,iim
    561           dyn1=dyn1+sinlondlon(ij)*dyq(ij,l)
    562           dyn2=dyn2+coslondlon(ij)*dyq(ij,l)
    563         ENDDO
    564         DO ij=1,iip1
    565           dyq(ij,l)=dyn1*sinlon(ij)+dyn2*coslon(ij)
    566         ENDDO
    567        
    568         DO ij=1,iip1
    569          dyq(ij,l)=0.
    570         ENDDO
    571 c ym tout cela ne sert pas a grand chose
     859        q(ij,l,iq2)=q(ij,l,iq)*Ratio(ij,l,iq2)
     860      enddo
     861    enddo
     862!$OMP END DO NOWAIT
     863  enddo
     864
     865
     866  RETURN
     867END SUBROUTINE vly_loc
     868
     869
     870
     871RECURSIVE SUBROUTINE vlz_loc(q,pente_max,masse,w,ijb_x,ije_x,iq)
     872  !
     873  ! Auteurs:   P.Le Van, F.Hourdin, F.Forget
     874  !
     875  !    ********************************************************************
     876  ! Shema  d'advection " pseudo amont " .
     877  !    ********************************************************************
     878  !    q,pbaru,pbarv,w sont des arguments d'entree  pour le s-pg ....
     879  ! dq         sont des arguments de sortie pour le s-pg ....
     880  !
     881  !
     882  !   --------------------------------------------------------------------
     883  USE parallel_lmdz
     884  USE vlz_mod
     885  USE infotrac, ONLY : nqtot,tracers, & ! CRisi                 &
     886        min_qParent,min_qMass,min_ratio ! MVals et CRisi
     887
     888  IMPLICIT NONE
     889  !
     890  include "dimensions.h"
     891  include "paramet.h"
     892  include "iniprint.h"
     893  !
     894  !
     895  !   Arguments:
     896  !   ----------
     897  REAL :: masse(ijb_u:ije_u,llm,nqtot),pente_max
     898  REAL :: q(ijb_u:ije_u,llm,nqtot)
     899  REAL :: w(ijb_u:ije_u,llm+1,nqtot)
     900  INTEGER :: iq
     901  !
     902  !  Local
     903  !   ---------
     904  !
     905  INTEGER :: i,ij,l,j,ii
     906
     907  REAL,DIMENSION(ijb_u:ije_u,llm+1) :: wresi,morig,qorig,dzqorig
     908  INTEGER,DIMENSION(ijb_u:ije_u,llm+1) :: lorig
     909  INTEGER,SAVE :: countcfl
     910!$OMP THREADPRIVATE(countcfl)
     911  !
     912  REAL :: newmasse
     913
     914  REAL :: dzqmax
     915  REAL :: sigw
     916
     917  LOGICAL :: testcpu
     918  SAVE testcpu
     919!$OMP THREADPRIVATE(testcpu)
     920  REAL :: temps0,temps1,temps2,temps3,temps4,temps5,second
     921  SAVE temps0,temps1,temps2,temps3,temps4,temps5
     922!$OMP THREADPRIVATE(temps0,temps1,temps2,temps3,temps4,temps5)
     923
     924  REAL :: SSUM
     925  EXTERNAL  SSUM
     926
     927  DATA testcpu/.false./
     928  DATA temps0,temps1,temps2,temps3,temps4,temps5/0.,0.,0.,0.,0.,0./
     929  INTEGER :: ijb,ije,ijb_x,ije_x
     930  LOGICAL,SAVE :: first=.TRUE.
     931!$OMP THREADPRIVATE(first)
     932
     933  ! !REAL masseq(ijb_u:ije_u,llm,nqtot),Ratio(ijb_u:ije_u,llm,nqtot) ! CRisi
     934  ! ! Ces varibles doivent être déclarées en pointer et en save dans
     935  ! ! vlz_loc si on veut qu'elles soient vues par tous les threads.
     936  INTEGER :: ifils,iq2 ! CRisi
     937
     938
     939  IF (first) THEN
     940   first=.FALSE.
     941  ENDIF
     942  !    On oriente tout dans le sens de la pression c'est a dire dans le
     943  !    sens de W
     944
     945  ! !write(*,*) 'vlsplt 926: entree dans vlz_loc, iq=',iq
     946#ifdef BIDON
     947  IF(testcpu) THEN
     948     temps0=second(0.)
     949  ENDIF
     950#endif
     951
     952  ijb=ijb_x
     953  ije=ije_x
     954
     955!$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
     956  DO l=2,llm
     957     DO ij=ijb,ije
     958        dzqw(ij,l)=q(ij,l-1,iq)-q(ij,l,iq)
     959        adzqw(ij,l)=abs(dzqw(ij,l))
     960     ENDDO
     961  ENDDO
     962!$OMP END DO
     963
     964!$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
     965  DO l=2,llm-1
     966     DO ij=ijb,ije
     967#ifdef CRAY
     968        dzq(ij,l)=0.5* &
     969              cvmgp(dzqw(ij,l)+dzqw(ij,l+1),0.,dzqw(ij,l)*dzqw(ij,l+1))
     970#else
     971        IF(dzqw(ij,l)*dzqw(ij,l+1).gt.0.) THEN
     972            dzq(ij,l)=0.5*(dzqw(ij,l)+dzqw(ij,l+1))
     973        ELSE
     974            dzq(ij,l)=0.
     975        ENDIF
     976#endif
     977        dzqmax=pente_max*min(adzqw(ij,l),adzqw(ij,l+1))
     978        dzq(ij,l)=sign(min(abs(dzq(ij,l)),dzqmax),dzq(ij,l))
     979     ENDDO
     980  ENDDO
     981!$OMP END DO NOWAIT
     982
     983!$OMP MASTER
     984  DO ij=ijb,ije
     985     dzq(ij,1)=0.
     986     dzq(ij,llm)=0.
     987  ENDDO
     988!$OMP END MASTER
     989!$OMP BARRIER
     990#ifdef BIDON
     991  IF(testcpu) THEN
     992     temps1=temps1+second(0.)-temps0
     993  ENDIF
     994#endif
     995
     996  !--------------------------------------------------------
     997  ! On repere les points qui violent le CFL (|w| > masse)
     998  !--------------------------------------------------------
     999
     1000  countcfl=0
     1001  ! print*,'vlz nouveau'
     1002!$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
     1003  DO l = 2,llm
     1004     DO ij = ijb,ije
     1005      IF(  (w(ij,l,iq)>0.AND.w(ij,l,iq)>masse(ij,l,iq)) &
     1006            .OR. (w(ij,l,iq)<=0.AND.ABS(w(ij,l,iq))>masse(ij,l-1,iq)) ) &
     1007            countcfl=countcfl+1
     1008     ENDDO
     1009  ENDDO
     1010!$OMP END DO NOWAIT
     1011
     1012  ! ---------------------------------------------------------------
     1013  !  Identification des mailles ou on viole le CFL : w > masse
     1014  ! ---------------------------------------------------------------
     1015
     1016  IF (countcfl==0) THEN
     1017
     1018  ! ---------------------------------------------------------------
     1019  !   .... calcul des termes d'advection verticale  .......
     1020  ! Dans le cas où le  |w| < masse partout.
     1021  ! Version d'origine
     1022  ! Pourrait etre enleve si on voit que le code plus general
     1023  ! est aussi rapide
     1024  ! ---------------------------------------------------------------
     1025
     1026  ! calcul de  - d( q   * w )/ d(sigma)    qu'on ajoute a  dq pour calculer dq
     1027
     1028  !  !write(*,*) 'vlz 982,ijb,ije=',ijb,ije
     1029!$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
     1030   DO l = 1,llm-1
     1031     do  ij = ijb,ije
     1032      IF(w(ij,l+1,iq).gt.0.) THEN
     1033         sigw=w(ij,l+1,iq)/masse(ij,l+1,iq)
     1034         wq(ij,l+1,iq)=w(ij,l+1,iq)*(q(ij,l+1,iq) &
     1035               +0.5*(1.-sigw)*dzq(ij,l+1))
     1036      ELSE
     1037         sigw=w(ij,l+1,iq)/masse(ij,l,iq)
     1038         wq(ij,l+1,iq)=w(ij,l+1,iq)*(q(ij,l,iq) &
     1039               -0.5*(1.+sigw)*dzq(ij,l))
    5721040      ENDIF
    573      
    574       IF (pole_sud) THEN
    575 
    576         DO ij=1,iip1
    577            dyq(ip1jm+ij,l)=q(ip1jm+ij-iip1,l,iq)-qpsn
    578         ENDDO
    579 
    580         dys1=0.
    581         dys2=0.
    582 
    583         DO ij=1,iim
    584           dys1=dys1+sinlondlon(ij)*dyq(ip1jm+ij,l)
    585           dys2=dys2+coslondlon(ij)*dyq(ip1jm+ij,l)
    586         ENDDO
    587 
    588         DO ij=1,iip1
    589           dyq(ip1jm+ij,l)=dys1*sinlon(ij)+dys2*coslon(ij)
    590         ENDDO
    591        
    592         DO ij=1,iip1
    593          dyq(ip1jm+ij,l)=0.
    594         ENDDO
    595 c ym tout cela ne sert pas a grand chose
     1041     ENDDO
     1042   ENDDO
     1043!$OMP END DO NOWAIT
     1044   ! !write(*,*) 'vlz 1001'
     1045
     1046  ELSE ! countcfl>=1
     1047
     1048  IF (prt_level>9) THEN
     1049    WRITE(lunout,*)'vlz passage dans le non local'
     1050  ENDIF
     1051  ! ---------------------------------------------------------------
     1052  !  Debut du traitement du cas ou on viole le CFL : w > masse
     1053  ! ---------------------------------------------------------------
     1054
     1055  ! Initialisation
     1056
     1057!$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
     1058   DO l = 2,llm
     1059     DO ij = ijb,ije
     1060        wresi(ij,l)=w(ij,l,iq)
     1061        wq(ij,l,iq)=0.
     1062        IF(w(ij,l,iq).gt.0.) THEN
     1063           lorig(ij,l)=l
     1064           morig(ij,l)=masse(ij,l,iq)
     1065           qorig(ij,l)=q(ij,l,iq)
     1066           dzqorig(ij,l)=dzq(ij,l)
     1067        ELSE
     1068           lorig(ij,l)=l-1
     1069           morig(ij,l)=masse(ij,l-1,iq)
     1070           qorig(ij,l)=q(ij,l-1,iq)
     1071           dzqorig(ij,l)=dzq(ij,l-1)
     1072        ENDIF
     1073     ENDDO
     1074   ENDDO
     1075!$OMP END DO NOWAIT
     1076
     1077  ! Reindicage vertical en accumulant les flux sur
     1078  !  les mailles qui viollent le CFL
     1079  !  on itère jusqu'à ce que tous les poins satisfassent
     1080  !  le critère
     1081  DO WHILE (countcfl>=1)
     1082    IF (prt_level>9) THEN
     1083      WRITE(lunout,*)'On viole le CFL Vertical sur ',countcfl,' pts'
     1084    ENDIF
     1085  countcfl=0
     1086
     1087!$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
     1088  DO l = 2,llm
     1089     DO ij = ijb,ije
     1090      IF (ABS(wresi(ij,l))>morig(ij,l)) THEN
     1091         countcfl=countcfl+1
     1092  ! rm : les 8 lignes ci dessous pourraient sans doute s'ecrire
     1093  ! avec la fonction sign
     1094         IF(w(ij,l,iq)>0.) THEN
     1095            wresi(ij,l)=wresi(ij,l)-morig(ij,l)
     1096            wq(ij,l,iq)=wq(ij,l,iq)+morig(ij,l)*qorig(ij,l)
     1097            lorig(ij,l)=lorig(ij,l)+1
     1098         ELSE
     1099            wresi(ij,l)=wresi(ij,l)+morig(ij,l)
     1100            wq(ij,l,iq)=wq(ij,l,iq)-morig(ij,l)*qorig(ij,l)
     1101            lorig(ij,l)=lorig(ij,l)-1
     1102         ENDIF
     1103         ! ! CRisi 24nov2020: ajout d'un message d'erreur clair au lieu d'un plantage
     1104         ! ! pour seg fault
     1105         if (lorig(ij,l).eq.0) then
     1106            call abort_gcm("vlz in vlsplt_loc", &
     1107                  "unfixable violation of CFL",1)
     1108         endif
     1109         morig(ij,l)=masse(ij,lorig(ij,l),iq)
     1110         qorig(ij,l)=q(ij,lorig(ij,l),iq)
     1111         dzqorig(ij,l)=dzq(ij,lorig(ij,l))
    5961112      ENDIF
    597 
    598 c   filtrage de la derivee
    599 
    600 c   calcul des pentes limites aux poles
    601 c ym partie inutile
    602 c      goto 8888
    603 c      fn=1.
    604 c      fs=1.
    605 c      DO ij=1,iim
    606 c         IF(pente_max*adyqv(ij).lt.abs(dyq(ij,l))) THEN
    607 c            fn=min(pente_max*adyqv(ij)/abs(dyq(ij,l)),fn)
    608 c         ENDIF
    609 c      IF(pente_max*adyqv(ij+ip1jm-iip1).lt.abs(dyq(ij+ip1jm,l))) THEN
    610 c         fs=min(pente_max*adyqv(ij+ip1jm-iip1)/abs(dyq(ij+ip1jm,l)),fs)
    611 c         ENDIF
    612 c      ENDDO
    613 c      DO ij=1,iip1
    614 c         dyq(ij,l)=fn*dyq(ij,l)
    615 c         dyq(ip1jm+ij,l)=fs*dyq(ip1jm+ij,l)
    616 c      ENDDO
    617 c 8888    continue
    618 
    619 
    620 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
    621 C  En memoire de dIFferents tests sur la
    622 C  limitation des pentes aux poles.
    623 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
    624 C     PRINT*,dyq(1)
    625 C     PRINT*,dyqv(iip1+1)
    626 C     appn=abs(dyq(1)/dyqv(iip1+1))
    627 C     PRINT*,dyq(ip1jm+1)
    628 C     PRINT*,dyqv(ip1jm-iip1+1)
    629 C     apps=abs(dyq(ip1jm+1)/dyqv(ip1jm-iip1+1))
    630 C     DO ij=2,iim
    631 C        appn=amax1(abs(dyq(ij)/dyqv(ij)),appn)
    632 C        apps=amax1(abs(dyq(ip1jm+ij)/dyqv(ip1jm-iip1+ij)),apps)
    633 C     ENDDO
    634 C     appn=min(pente_max/appn,1.)
    635 C     apps=min(pente_max/apps,1.)
    636 C
    637 C
    638 C   cas ou on a un extremum au pole
    639 C
    640 C     IF(dyqv(ismin(iim,dyqv,1))*dyqv(ismax(iim,dyqv,1)).le.0.)
    641 C    &   appn=0.
    642 C     IF(dyqv(ismax(iim,dyqv(ip1jm-iip1+1),1)+ip1jm-iip1+1)*
    643 C    &   dyqv(ismin(iim,dyqv(ip1jm-iip1+1),1)+ip1jm-iip1+1).le.0.)
    644 C    &   apps=0.
    645 C
    646 C   limitation des pentes aux poles
    647 C     DO ij=1,iip1
    648 C        dyq(ij)=appn*dyq(ij)
    649 C        dyq(ip1jm+ij)=apps*dyq(ip1jm+ij)
    650 C     ENDDO
    651 C
    652 C   test
    653 C      DO ij=1,iip1
    654 C         dyq(iip1+ij)=0.
    655 C         dyq(ip1jm+ij-iip1)=0.
    656 C      ENDDO
    657 C      DO ij=1,ip1jmp1
    658 C         dyq(ij)=dyq(ij)*cos(rlatu((ij-1)/iip1+1))
    659 C      ENDDO
    660 C
    661 C changement 10 07 96
    662 C     IF(dyqv(ismin(iim,dyqv,1))*dyqv(ismax(iim,dyqv,1)).le.0.)
    663 C    &   THEN
    664 C        DO ij=1,iip1
    665 C           dyqmax(ij)=0.
    666 C        ENDDO
    667 C     ELSE
    668 C        DO ij=1,iip1
    669 C           dyqmax(ij)=pente_max*abs(dyqv(ij))
    670 C        ENDDO
    671 C     ENDIF
    672 C
    673 C     IF(dyqv(ismax(iim,dyqv(ip1jm-iip1+1),1)+ip1jm-iip1+1)*
    674 C    & dyqv(ismin(iim,dyqv(ip1jm-iip1+1),1)+ip1jm-iip1+1).le.0.)
    675 C    &THEN
    676 C        DO ij=ip1jm+1,ip1jmp1
    677 C           dyqmax(ij)=0.
    678 C        ENDDO
    679 C     ELSE
    680 C        DO ij=ip1jm+1,ip1jmp1
    681 C           dyqmax(ij)=pente_max*abs(dyqv(ij-iip1))
    682 C        ENDDO
    683 C     ENDIF
    684 C   fin changement 10 07 96
    685 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
    686 
    687 c   calcul des pentes limitees
    688       ijb=ij_begin-iip1
    689       ije=ij_end+iip1
    690       if (pole_nord) ijb=ij_begin+iip1
    691       if (pole_sud)  ije=ij_end-iip1
    692 
     1113     ENDDO
     1114  ENDDO
     1115!$OMP END DO NOWAIT
     1116
     1117  ENDDO ! WHILE (countcfl>=1)
     1118
     1119!$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
     1120   DO l = 2,llm
     1121     do  ij = ijb,ije
     1122      sigw=wresi(ij,l)/morig(ij,l)
     1123      IF(w(ij,l,iq).gt.0.) THEN
     1124         wq(ij,l,iq)=wq(ij,l,iq)+wresi(ij,l)*(qorig(ij,l) &
     1125               +0.5*(1.-sigw)*dzqorig(ij,l))
     1126      ELSE
     1127         wq(ij,l,iq)=wq(ij,l,iq)+wresi(ij,l)*(qorig(ij,l) &
     1128               -0.5*(1.+sigw)*dzqorig(ij,l))
     1129      ENDIF
     1130     ENDDO
     1131   ENDDO
     1132!$OMP END DO NOWAIT
     1133
     1134
     1135   ENDIF ! councfl=0
     1136
     1137
     1138
     1139!$OMP MASTER
     1140   DO ij=ijb,ije
     1141      wq(ij,llm+1,iq)=0.
     1142      wq(ij,1,iq)=0.
     1143   ENDDO
     1144!$OMP END MASTER
     1145!$OMP BARRIER
     1146
     1147  ! CRisi: appel récursif de l'advection sur les fils.
     1148  ! Il faut faire ça avant d'avoir mis à jour q et masse
     1149  ! write(*,*)'vlsplt 942: iq,nqChildren(iq)=',iq,tracers(iq)%nqChildren
     1150  do ifils=1,tracers(iq)%nqDescen
     1151    iq2=tracers(iq)%iqDescen(ifils)
     1152!$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
     1153    DO l=1,llm
    6931154      DO ij=ijb,ije
    694          IF(dyqv(ij)*dyqv(ij-iip1).gt.0.) THEN
    695             dyq(ij,l)=sign(min(abs(dyq(ij,l)),dyqmax(ij)),dyq(ij,l))
    696          ELSE
    697             dyq(ij,l)=0.
    698          ENDIF
    699       ENDDO
    700 
    701       ENDDO
    702 c$OMP END DO NOWAIT
    703 
    704       ijb=ij_begin-iip1
    705       ije=ij_end
    706       if (pole_nord) ijb=ij_begin
    707       if (pole_sud)  ije=ij_end-iip1
    708 
    709 c$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
    710       DO l=1,llm
    711        DO ij=ijb,ije
    712           IF(masse_adv_v(ij,l).gt.0) THEN
    713               qbyv(ij,l)=q(ij+iip1,l,iq)+dyq(ij+iip1,l)*
    714      ,                   0.5*(1.-masse_adv_v(ij,l)
    715      ,                   /masse(ij+iip1,l,iq))
    716           ELSE
    717               qbyv(ij,l)=q(ij,l,iq)-dyq(ij,l)*
    718      ,                   0.5*(1.+masse_adv_v(ij,l)/masse(ij,l,iq))
    719           ENDIF
    720           qbyv(ij,l)=masse_adv_v(ij,l)*qbyv(ij,l)
    721        ENDDO
    722       ENDDO
    723 c$OMP END DO NOWAIT
    724 
    725 ! CRisi: appel récursif de l'advection sur les fils.
    726 ! Il faut faire ça avant d'avoir mis à jour q et masse
    727 !     write(*,*)'vly 689: iq,nqChildren(iq)=',iq,tracers(iq)%nqChildren
    728 
    729       ijb=ij_begin-2*iip1
    730       ije=ij_end+2*iip1
    731       ijbm=ij_begin-iip1
    732       ijem=ij_end+iip1
    733       if (pole_nord) ijb=ij_begin
    734       if (pole_sud)  ije=ij_end 
    735       if (pole_nord) ijbm=ij_begin
    736       if (pole_sud)  ijem=ij_end
    737 
    738       do ifils=1,tracers(iq)%nqDescen
    739         iq2=tracers(iq)%iqDescen(ifils)
    740 c$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
    741         DO l=1,llm
    742         ! modif des bornes: CRisi 16 nov 2020
    743         ! d'abord masse avec bornes corrigées
    744           DO ij=ijbm,ijem
    745           !MVals: veiller a ce qu'on n'ait pas de denominateur nul
    746             masse(ij,l,iq2)=max(masse(ij,l,iq)*q(ij,l,iq),min_qMass)
    747           enddo
    748 
    749           ! ensuite Ratio avec anciennes bornes
    750           DO ij=ijb,ije
    751           !MVals: veiller a ce qu'on n'ait pas de denominateur nul
    752             if (q(ij,l,iq).gt.min_qParent) then ! modif 13 nov 2020
    753               Ratio(ij,l,iq2)=q(ij,l,iq2)/q(ij,l,iq)
    754             else
    755               Ratio(ij,l,iq2)=min_ratio 
    756             endif     
    757           enddo !DO ij=ijbm,ijem 
    758         enddo !DO l=1,llm
    759 c$OMP END DO NOWAIT
     1155       ! !MVals: veiller a ce qu'on n'ait pas de denominateur nul
     1156        masse(ij,l,iq2)=max(masse(ij,l,iq)*q(ij,l,iq),min_qMass)
     1157        if (q(ij,l,iq).gt.min_qParent) then
     1158          Ratio(ij,l,iq2)=q(ij,l,iq2)/q(ij,l,iq)
     1159        else
     1160          Ratio(ij,l,iq2)=min_ratio
     1161        endif
     1162        ! !wq(ij,l,iq2)=wq(ij,l,iq) ! correction bug le 15mai2015
     1163        w(ij,l,iq2)=wq(ij,l,iq)
    7601164      enddo
    761 
    762       do ifils=1,tracers(iq)%nqChildren
    763         iq2=tracers(iq)%iqDescen(ifils)
    764         call vly_loc(Ratio,pente_max,masse,qbyv,iq2)
     1165    enddo
     1166!$OMP END DO NOWAIT
     1167  enddo
     1168!$OMP BARRIER
     1169
     1170  do ifils=1,tracers(iq)%nqChildren
     1171    iq2=tracers(iq)%iqDescen(ifils)
     1172    call vlz_loc(Ratio,pente_max,masse,w,ijb_x,ije_x,iq2)
     1173  enddo
     1174  ! end CRisi
     1175
     1176  ! CRisi: On rajoute ici une barrière car on veut être sur que tous les
     1177  ! wq soient synchronisés
     1178
     1179!$OMP BARRIER
     1180!$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
     1181  DO l=1,llm
     1182     DO ij=ijb,ije
     1183        newmasse=masse(ij,l,iq)+w(ij,l+1,iq)-w(ij,l,iq)
     1184        q(ij,l,iq)=(q(ij,l,iq)*masse(ij,l,iq) &
     1185              +wq(ij,l+1,iq)-wq(ij,l,iq)) &
     1186              /newmasse
     1187        masse(ij,l,iq)=newmasse
     1188     ENDDO
     1189  ENDDO
     1190!$OMP END DO NOWAIT
     1191
     1192
     1193  ! retablir les fils en rapport de melange par rapport a l'air:
     1194  do ifils=1,tracers(iq)%nqDescen
     1195    iq2=tracers(iq)%iqDescen(ifils)
     1196!$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
     1197    DO l=1,llm
     1198      DO ij=ijb,ije
     1199        q(ij,l,iq2)=q(ij,l,iq)*Ratio(ij,l,iq2)
    7651200      enddo
    766 ! end CRisi
    767      
    768       ijb=ij_begin
    769       ije=ij_end
    770       if (pole_nord) ijb=ij_begin+iip1
    771       if (pole_sud)  ije=ij_end-iip1
    772      
    773 c$OMP DO SCHEDULE(STATIC,OMP_CHUNK)     
    774       DO l=1,llm
    775          DO ij=ijb,ije
    776             newmasse=masse(ij,l,iq)
    777      &         +masse_adv_v(ij,l)-masse_adv_v(ij-iip1,l)
    778 
    779             q(ij,l,iq)=(q(ij,l,iq)*masse(ij,l,iq)+qbyv(ij,l)
    780      &         -qbyv(ij-iip1,l))/newmasse
    781 
    782             masse(ij,l,iq)=newmasse
    783 
    784          ENDDO
    785 
    786 
    787 c.-. ancienne version
    788 c        convpn=SSUM(iim,qbyv(1,l),1)/apoln
    789 c        convmpn=ssum(iim,masse_adv_v(1,l),1)/apoln
    790          if (pole_nord) then
    791            convpn=SSUM(iim,qbyv(1,l),1)
    792            convmpn=ssum(iim,masse_adv_v(1,l),1)
    793            massepn=ssum(iim,masse(1,l,iq),1)
    794            qpn=0.
    795            do ij=1,iim
    796               qpn=qpn+masse(ij,l,iq)*q(ij,l,iq)
    797            enddo
    798            qpn=(qpn+convpn)/(massepn+convmpn)
    799            do ij=1,iip1
    800               q(ij,l,iq)=qpn
    801            enddo
    802          endif
    803          
    804 c        convps=-SSUM(iim,qbyv(ip1jm-iim,l),1)/apols
    805 c        convmps=-ssum(iim,masse_adv_v(ip1jm-iim,l),1)/apols
    806          
    807          if (pole_sud) then
    808          
    809            convps=-SSUM(iim,qbyv(ip1jm-iim,l),1)
    810            convmps=-ssum(iim,masse_adv_v(ip1jm-iim,l),1)
    811            masseps=ssum(iim, masse(ip1jm+1,l,iq),1)
    812            qps=0.
    813            do ij = ip1jm+1,ip1jmp1-1
    814               qps=qps+masse(ij,l,iq)*q(ij,l,iq)
    815            enddo
    816            qps=(qps+convps)/(masseps+convmps)
    817            do ij=ip1jm+1,ip1jmp1
    818               q(ij,l,iq)=qps
    819            enddo
    820          endif
    821 c.-. fin ancienne version
    822 
    823 c._. nouvelle version
    824 c        convpn=SSUM(iim,qbyv(1,l),1)
    825 c        convmpn=ssum(iim,masse_adv_v(1,l),1)
    826 c        oldmasse=ssum(iim,masse(1,l),1)
    827 c        newmasse=oldmasse+convmpn
    828 c        newq=(q(1,l)*oldmasse+convpn)/newmasse
    829 c        newmasse=newmasse/apoln
    830 c        DO ij = 1,iip1
    831 c           q(ij,l)=newq
    832 c           masse(ij,l,iq)=newmasse*aire(ij)
    833 c        ENDDO
    834 c        convps=-SSUM(iim,qbyv(ip1jm-iim,l),1)
    835 c        convmps=-ssum(iim,masse_adv_v(ip1jm-iim,l),1)
    836 c        oldmasse=ssum(iim,masse(ip1jm-iim,l),1)
    837 c        newmasse=oldmasse+convmps
    838 c        newq=(q(ip1jmp1,l)*oldmasse+convps)/newmasse
    839 c        newmasse=newmasse/apols
    840 c        DO ij = ip1jm+1,ip1jmp1
    841 c           q(ij,l)=newq
    842 c           masse(ij,l,iq)=newmasse*aire(ij)
    843 c        ENDDO
    844 c._. fin nouvelle version
    845       ENDDO
    846 c$OMP END DO NOWAIT
    847 
    848 ! retablir les fils en rapport de melange par rapport a l'air:
    849       ijb=ij_begin
    850       ije=ij_end
    851 !      if (pole_nord) ijb=ij_begin
    852 !      if (pole_sud)  ije=ij_end
    853 
    854       do ifils=1,tracers(iq)%nqDescen
    855         iq2=tracers(iq)%iqDescen(ifils)
    856 c$OMP DO SCHEDULE(STATIC,OMP_CHUNK)   
    857         DO l=1,llm
    858           DO ij=ijb,ije
    859             q(ij,l,iq2)=q(ij,l,iq)*Ratio(ij,l,iq2)           
    860           enddo
    861         enddo
    862 c$OMP END DO NOWAIT
    863       enddo
    864 
    865 
    866       RETURN
    867       END
    868      
    869      
    870      
    871       RECURSIVE SUBROUTINE vlz_loc(q,pente_max,masse,w,ijb_x,ije_x,iq)
    872 c
    873 c     Auteurs:   P.Le Van, F.Hourdin, F.Forget
    874 c
    875 c    ********************************************************************
    876 c     Shema  d'advection " pseudo amont " .
    877 c    ********************************************************************
    878 c    q,pbaru,pbarv,w sont des arguments d'entree  pour le s-pg ....
    879 c     dq               sont des arguments de sortie pour le s-pg ....
    880 c
    881 c
    882 c   --------------------------------------------------------------------
    883       USE parallel_lmdz
    884       USE vlz_mod
    885       USE infotrac, ONLY : nqtot,tracers, ! CRisi                 &
    886      &                     min_qParent,min_qMass,min_ratio ! MVals et CRisi
    887      
    888       IMPLICIT NONE
    889 c
    890       include "dimensions.h"
    891       include "paramet.h"
    892       include "iniprint.h"
    893 c
    894 c
    895 c   Arguments:
    896 c   ----------
    897       REAL masse(ijb_u:ije_u,llm,nqtot),pente_max
    898       REAL q(ijb_u:ije_u,llm,nqtot)
    899       REAL w(ijb_u:ije_u,llm+1,nqtot)
    900       INTEGER iq
    901 c
    902 c      Local
    903 c   ---------
    904 c
    905       INTEGER i,ij,l,j,ii
    906 
    907       REAL,DIMENSION(ijb_u:ije_u,llm+1) :: wresi,morig,qorig,dzqorig
    908       INTEGER,DIMENSION(ijb_u:ije_u,llm+1) :: lorig
    909       INTEGER,SAVE :: countcfl
    910 !$OMP THREADPRIVATE(countcfl)
    911 c
    912       REAL newmasse
    913 
    914       REAL dzqmax
    915       REAL sigw
    916 
    917       LOGICAL testcpu
    918       SAVE testcpu
    919 c$OMP THREADPRIVATE(testcpu)
    920       REAL temps0,temps1,temps2,temps3,temps4,temps5,second
    921       SAVE temps0,temps1,temps2,temps3,temps4,temps5
    922 c$OMP THREADPRIVATE(temps0,temps1,temps2,temps3,temps4,temps5)
    923 
    924       REAL      SSUM
    925       EXTERNAL  SSUM
    926 
    927       DATA testcpu/.false./
    928       DATA temps0,temps1,temps2,temps3,temps4,temps5/0.,0.,0.,0.,0.,0./
    929       INTEGER ijb,ije,ijb_x,ije_x
    930       LOGICAL,SAVE :: first=.TRUE.
    931 !$OMP THREADPRIVATE(first)
    932 
    933       !REAL masseq(ijb_u:ije_u,llm,nqtot),Ratio(ijb_u:ije_u,llm,nqtot) ! CRisi
    934       ! Ces varibles doivent être déclarées en pointer et en save dans
    935       ! vlz_loc si on veut qu'elles soient vues par tous les threads. 
    936       INTEGER ifils,iq2 ! CRisi
    937 
    938 
    939       IF (first) THEN
    940        first=.FALSE.
    941       ENDIF             
    942 c    On oriente tout dans le sens de la pression c'est a dire dans le
    943 c    sens de W
    944 
    945       !write(*,*) 'vlsplt 926: entree dans vlz_loc, iq=',iq
    946 #ifdef BIDON
    947       IF(testcpu) THEN
    948          temps0=second(0.)
    949       ENDIF
    950 #endif
    951 
    952       ijb=ijb_x
    953       ije=ije_x
    954 
    955 c$OMP DO SCHEDULE(STATIC,OMP_CHUNK)     
    956       DO l=2,llm
    957          DO ij=ijb,ije
    958             dzqw(ij,l)=q(ij,l-1,iq)-q(ij,l,iq)
    959             adzqw(ij,l)=abs(dzqw(ij,l))
    960          ENDDO
    961       ENDDO
    962 c$OMP END DO
    963 
    964 c$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
    965       DO l=2,llm-1
    966          DO ij=ijb,ije
    967 #ifdef CRAY
    968             dzq(ij,l)=0.5*
    969      ,      cvmgp(dzqw(ij,l)+dzqw(ij,l+1),0.,dzqw(ij,l)*dzqw(ij,l+1))
    970 #else
    971             IF(dzqw(ij,l)*dzqw(ij,l+1).gt.0.) THEN
    972                 dzq(ij,l)=0.5*(dzqw(ij,l)+dzqw(ij,l+1))
    973             ELSE
    974                 dzq(ij,l)=0.
    975             ENDIF
    976 #endif
    977             dzqmax=pente_max*min(adzqw(ij,l),adzqw(ij,l+1))
    978             dzq(ij,l)=sign(min(abs(dzq(ij,l)),dzqmax),dzq(ij,l))
    979          ENDDO
    980       ENDDO
    981 c$OMP END DO NOWAIT
    982 
    983 c$OMP MASTER
    984       DO ij=ijb,ije
    985          dzq(ij,1)=0.
    986          dzq(ij,llm)=0.
    987       ENDDO
    988 c$OMP END MASTER
    989 c$OMP BARRIER
    990 #ifdef BIDON
    991       IF(testcpu) THEN
    992          temps1=temps1+second(0.)-temps0
    993       ENDIF
    994 #endif
    995 
    996 !--------------------------------------------------------
    997 ! On repere les points qui violent le CFL (|w| > masse)
    998 !--------------------------------------------------------
    999 
    1000       countcfl=0
    1001 !     print*,'vlz nouveau'
    1002 c$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
    1003       DO l = 2,llm
    1004          DO ij = ijb,ije
    1005           IF(  (w(ij,l,iq)>0.AND.w(ij,l,iq)>masse(ij,l,iq))
    1006      s    .OR. (w(ij,l,iq)<=0.AND.ABS(w(ij,l,iq))>masse(ij,l-1,iq)) )
    1007      s    countcfl=countcfl+1
    1008          ENDDO
    1009       ENDDO
    1010 c$OMP END DO NOWAIT   
    1011 
    1012 c ---------------------------------------------------------------
    1013 c  Identification des mailles ou on viole le CFL : w > masse
    1014 c ---------------------------------------------------------------
    1015 
    1016       IF (countcfl==0) THEN
    1017 
    1018 c ---------------------------------------------------------------
    1019 c   .... calcul des termes d'advection verticale  .......
    1020 c     Dans le cas où le  |w| < masse partout.
    1021 c     Version d'origine
    1022 c     Pourrait etre enleve si on voit que le code plus general
    1023 c     est aussi rapide
    1024 c ---------------------------------------------------------------
    1025 
    1026 c calcul de  - d( q   * w )/ d(sigma)    qu'on ajoute a  dq pour calculer dq
    1027 
    1028        !write(*,*) 'vlz 982,ijb,ije=',ijb,ije
    1029 c$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
    1030        DO l = 1,llm-1
    1031          do  ij = ijb,ije
    1032           IF(w(ij,l+1,iq).gt.0.) THEN
    1033              sigw=w(ij,l+1,iq)/masse(ij,l+1,iq)
    1034              wq(ij,l+1,iq)=w(ij,l+1,iq)*(q(ij,l+1,iq)
    1035      :           +0.5*(1.-sigw)*dzq(ij,l+1))
    1036           ELSE
    1037              sigw=w(ij,l+1,iq)/masse(ij,l,iq)
    1038              wq(ij,l+1,iq)=w(ij,l+1,iq)*(q(ij,l,iq)
    1039      :           -0.5*(1.+sigw)*dzq(ij,l))
    1040           ENDIF
    1041          ENDDO
    1042        ENDDO
    1043 c$OMP END DO NOWAIT   
    1044        !write(*,*) 'vlz 1001'   
    1045 
    1046       ELSE ! countcfl>=1
    1047 
    1048       IF (prt_level>9) THEN
    1049         WRITE(lunout,*)'vlz passage dans le non local'
    1050       ENDIF
    1051 c ---------------------------------------------------------------
    1052 c  Debut du traitement du cas ou on viole le CFL : w > masse
    1053 c ---------------------------------------------------------------
    1054 
    1055 c Initialisation
    1056 
    1057 c$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
    1058        DO l = 2,llm
    1059          DO ij = ijb,ije
    1060             wresi(ij,l)=w(ij,l,iq)
    1061             wq(ij,l,iq)=0.
    1062             IF(w(ij,l,iq).gt.0.) THEN
    1063                lorig(ij,l)=l
    1064                morig(ij,l)=masse(ij,l,iq)
    1065                qorig(ij,l)=q(ij,l,iq)
    1066                dzqorig(ij,l)=dzq(ij,l)
    1067             ELSE
    1068                lorig(ij,l)=l-1
    1069                morig(ij,l)=masse(ij,l-1,iq)
    1070                qorig(ij,l)=q(ij,l-1,iq)
    1071                dzqorig(ij,l)=dzq(ij,l-1)
    1072             ENDIF
    1073          ENDDO
    1074        ENDDO
    1075 c$OMP END DO NOWAIT
    1076 
    1077 c Reindicage vertical en accumulant les flux sur
    1078 c  les mailles qui viollent le CFL
    1079 c  on itère jusqu'à ce que tous les poins satisfassent
    1080 c  le critère
    1081       DO WHILE (countcfl>=1)
    1082         IF (prt_level>9) THEN
    1083           WRITE(lunout,*)'On viole le CFL Vertical sur ',countcfl,' pts'
    1084         ENDIF
    1085       countcfl=0
    1086 
    1087 c$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
    1088       DO l = 2,llm
    1089          DO ij = ijb,ije
    1090           IF (ABS(wresi(ij,l))>morig(ij,l)) THEN
    1091              countcfl=countcfl+1
    1092 ! rm : les 8 lignes ci dessous pourraient sans doute s'ecrire
    1093 ! avec la fonction sign
    1094              IF(w(ij,l,iq)>0.) THEN
    1095                 wresi(ij,l)=wresi(ij,l)-morig(ij,l)
    1096                 wq(ij,l,iq)=wq(ij,l,iq)+morig(ij,l)*qorig(ij,l)
    1097                 lorig(ij,l)=lorig(ij,l)+1
    1098              ELSE
    1099                 wresi(ij,l)=wresi(ij,l)+morig(ij,l)
    1100                 wq(ij,l,iq)=wq(ij,l,iq)-morig(ij,l)*qorig(ij,l)
    1101                 lorig(ij,l)=lorig(ij,l)-1
    1102              ENDIF
    1103              ! CRisi 24nov2020: ajout d'un message d'erreur clair au lieu d'un plantage
    1104              ! pour seg fault
    1105              if (lorig(ij,l).eq.0) then
    1106                 call abort_gcm("vlz in vlsplt_loc",
    1107      :           "unfixable violation of CFL",1)
    1108              endif
    1109              morig(ij,l)=masse(ij,lorig(ij,l),iq)
    1110              qorig(ij,l)=q(ij,lorig(ij,l),iq)
    1111              dzqorig(ij,l)=dzq(ij,lorig(ij,l))
    1112           ENDIF
    1113          ENDDO
    1114       ENDDO
    1115 c$OMP END DO NOWAIT
    1116 
    1117       ENDDO ! WHILE (countcfl>=1)
    1118 
    1119 c$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
    1120        DO l = 2,llm
    1121          do  ij = ijb,ije
    1122           sigw=wresi(ij,l)/morig(ij,l)
    1123           IF(w(ij,l,iq).gt.0.) THEN
    1124              wq(ij,l,iq)=wq(ij,l,iq)+wresi(ij,l)*(qorig(ij,l)
    1125      :           +0.5*(1.-sigw)*dzqorig(ij,l))
    1126           ELSE
    1127              wq(ij,l,iq)=wq(ij,l,iq)+wresi(ij,l)*(qorig(ij,l)
    1128      :           -0.5*(1.+sigw)*dzqorig(ij,l))
    1129           ENDIF
    1130          ENDDO
    1131        ENDDO
    1132 c$OMP END DO NOWAIT   
    1133 
    1134 
    1135        ENDIF ! councfl=0
    1136 
    1137 
    1138 
    1139 c$OMP MASTER
    1140        DO ij=ijb,ije
    1141           wq(ij,llm+1,iq)=0.
    1142           wq(ij,1,iq)=0.
    1143        ENDDO
    1144 c$OMP END MASTER
    1145 c$OMP BARRIER
    1146 
    1147 ! CRisi: appel récursif de l'advection sur les fils.
    1148 ! Il faut faire ça avant d'avoir mis à jour q et masse
    1149 !     write(*,*)'vlsplt 942: iq,nqChildren(iq)=',iq,tracers(iq)%nqChildren
    1150       do ifils=1,tracers(iq)%nqDescen
    1151         iq2=tracers(iq)%iqDescen(ifils)
    1152 c$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
    1153         DO l=1,llm
    1154           DO ij=ijb,ije
    1155            !MVals: veiller a ce qu'on n'ait pas de denominateur nul
    1156             masse(ij,l,iq2)=max(masse(ij,l,iq)*q(ij,l,iq),min_qMass)
    1157             if (q(ij,l,iq).gt.min_qParent) then
    1158               Ratio(ij,l,iq2)=q(ij,l,iq2)/q(ij,l,iq)
    1159             else
    1160               Ratio(ij,l,iq2)=min_ratio
    1161             endif
    1162             !wq(ij,l,iq2)=wq(ij,l,iq) ! correction bug le 15mai2015
    1163             w(ij,l,iq2)=wq(ij,l,iq)
    1164           enddo   
    1165         enddo
    1166 c$OMP END DO NOWAIT
    1167       enddo
    1168 c$OMP BARRIER
    1169 
    1170       do ifils=1,tracers(iq)%nqChildren
    1171         iq2=tracers(iq)%iqDescen(ifils)
    1172         call vlz_loc(Ratio,pente_max,masse,w,ijb_x,ije_x,iq2)
    1173       enddo
    1174 ! end CRisi 
    1175 
    1176 ! CRisi: On rajoute ici une barrière car on veut être sur que tous les
    1177 ! wq soient synchronisés
    1178 
    1179 c$OMP BARRIER
    1180 c$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
    1181       DO l=1,llm
    1182          DO ij=ijb,ije
    1183             newmasse=masse(ij,l,iq)+w(ij,l+1,iq)-w(ij,l,iq)
    1184             q(ij,l,iq)=(q(ij,l,iq)*masse(ij,l,iq)
    1185      &         +wq(ij,l+1,iq)-wq(ij,l,iq))
    1186      &         /newmasse
    1187             masse(ij,l,iq)=newmasse
    1188          ENDDO
    1189       ENDDO
    1190 c$OMP END DO NOWAIT
    1191 
    1192      
    1193 ! retablir les fils en rapport de melange par rapport a l'air:
    1194       do ifils=1,tracers(iq)%nqDescen
    1195         iq2=tracers(iq)%iqDescen(ifils)
    1196 c$OMP DO SCHEDULE(STATIC,OMP_CHUNK)   
    1197         DO l=1,llm
    1198           DO ij=ijb,ije
    1199             q(ij,l,iq2)=q(ij,l,iq)*Ratio(ij,l,iq2)           
    1200           enddo
    1201         enddo
    1202 c$OMP END DO NOWAIT
    1203       enddo
    1204 
    1205       RETURN
    1206       END
    1207 c      SUBROUTINE minmaxq(zq,qmin,qmax,comment)
    1208 c
    1209 c      INCLUDE "dimensions.h"
    1210 c      INCLUDE "paramet.h"
    1211 
    1212 c      CHARACTER*(*) comment
    1213 c      real qmin,qmax
    1214 c      real zq(ip1jmp1,llm)
    1215 
    1216 c      INTEGER jadrs(ip1jmp1), jbad, k, i
    1217 
    1218 
    1219 c      DO k = 1, llm
    1220 c         jbad = 0
    1221 c         DO i = 1, ip1jmp1
    1222 c         IF (zq(i,k).GT.qmax .OR. zq(i,k).LT.qmin) THEN
    1223 c            jbad = jbad + 1
    1224 c            jadrs(jbad) = i
    1225 c         ENDIF
    1226 c         ENDDO
    1227 c         IF (jbad.GT.0) THEN
    1228 c         PRINT*, comment
    1229 c         DO i = 1, jbad
    1230 cc            PRINT*, "i,k,zq=", jadrs(i),k,zq(jadrs(i),k)
    1231 c         ENDDO
    1232 c         ENDIF
    1233 c      ENDDO
    1234 
    1235 c      return
    1236 c      end
    1237 
    1238 
    1239 
    1240 
     1201    enddo
     1202!$OMP END DO NOWAIT
     1203  enddo
     1204
     1205  RETURN
     1206END SUBROUTINE vlz_loc
     1207 ! SUBROUTINE minmaxq(zq,qmin,qmax,comment)
     1208!
     1209!  INCLUDE "dimensions.h"
     1210!  INCLUDE "paramet.h"
     1211
     1212!  CHARACTER*(*) comment
     1213!  real qmin,qmax
     1214!  real zq(ip1jmp1,llm)
     1215
     1216!  INTEGER jadrs(ip1jmp1), jbad, k, i
     1217
     1218
     1219!  DO k = 1, llm
     1220!     jbad = 0
     1221!     DO i = 1, ip1jmp1
     1222!     IF (zq(i,k).GT.qmax .OR. zq(i,k).LT.qmin) THEN
     1223!        jbad = jbad + 1
     1224!        jadrs(jbad) = i
     1225!     ENDIF
     1226!     ENDDO
     1227!     IF (jbad.GT.0) THEN
     1228!     PRINT*, comment
     1229!     DO i = 1, jbad
     1230!c            PRINT*, "i,k,zq=", jadrs(i),k,zq(jadrs(i),k)
     1231!     ENDDO
     1232!     ENDIF
     1233!  ENDDO
     1234
     1235!  return
     1236!  end
     1237
     1238
     1239
     1240
Note: See TracChangeset for help on using the changeset viewer.