Ignore:
Timestamp:
Jun 17, 2022, 4:24:49 PM (2 years ago)
Author:
lguez
Message:

Sync latest trunk changes to branch LMDZ-ECRAD.

Location:
LMDZ6/branches/LMDZ-ECRAD
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • LMDZ6/branches/LMDZ-ECRAD

  • LMDZ6/branches/LMDZ-ECRAD/libf/dyn3d/advtrac.F90

    r2622 r4171  
    11! $Id$
    22
    3 SUBROUTINE advtrac(pbaru,pbarv , p,  masse,q,iapptrac,teta, flxw, pk)
    4   !     Auteur :  F. Hourdin
    5   !
    6   !     Modif. P. Le Van     (20/12/97)
    7   !            F. Codron     (10/99)
    8   !            D. Le Croller (07/2001)
    9   !            M.A Filiberti (04/2002)
    10   !
    11   USE infotrac, ONLY: nqtot, iadv,nqperes,ok_iso_verif
    12   USE control_mod, ONLY: iapp_tracvl, day_step
    13   USE comconst_mod, ONLY: dtvr
    14 
    15   IMPLICIT NONE
    16   !
    17   include "dimensions.h"
    18   include "paramet.h"
    19   include "comdissip.h"
    20   include "comgeom2.h"
    21   include "description.h"
    22   include "iniprint.h"
    23 
    24   !-------------------------------------------------------------------
    25   !     Arguments
    26   !-------------------------------------------------------------------
    27   INTEGER,INTENT(OUT) :: iapptrac
    28   REAL,INTENT(IN) :: pbaru(ip1jmp1,llm)
    29   REAL,INTENT(IN) :: pbarv(ip1jm,llm)
    30   REAL,INTENT(INOUT) :: q(ip1jmp1,llm,nqtot)
    31   REAL,INTENT(IN) :: masse(ip1jmp1,llm)
    32   REAL,INTENT(IN) :: p( ip1jmp1,llmp1 )
    33   REAL,INTENT(IN) :: teta(ip1jmp1,llm)
    34   REAL,INTENT(IN) :: pk(ip1jmp1,llm)
    35   REAL,INTENT(OUT) :: flxw(ip1jmp1,llm)
    36   !-------------------------------------------------------------------
    37   !     Ajout PPM
    38   !--------------------------------------------------------
    39   REAL massebx(ip1jmp1,llm),masseby(ip1jm,llm)
    40   !-------------------------------------------------------------
    41   !     Variables locales
    42   !-------------------------------------------------------------
    43 
    44   REAL pbaruc(ip1jmp1,llm),pbarvc(ip1jm,llm)
    45   REAL massem(ip1jmp1,llm),zdp(ip1jmp1)
    46   REAL pbarug(ip1jmp1,llm),pbarvg(ip1jm,llm),wg(ip1jmp1,llm)
    47   REAL (kind=kind(1.d0)) :: t_initial, t_final, tps_cpu
    48   INTEGER iadvtr
    49   INTEGER ij,l,iq,iiq
    50   REAL zdpmin, zdpmax
    51   EXTERNAL  minmax
    52   SAVE iadvtr, massem, pbaruc, pbarvc
    53   DATA iadvtr/0/
    54   !----------------------------------------------------------
    55   !     Rajouts pour PPM
    56   !----------------------------------------------------------
    57   INTEGER indice,n
    58   REAL dtbon ! Pas de temps adaptatif pour que CFL<1
    59   REAL CFLmaxz,aaa,bbb ! CFL maximum
    60   REAL psppm(iim,jjp1) ! pression  au sol
    61   REAL unatppm(iim,jjp1,llm),vnatppm(iim,jjp1,llm)
    62   REAL qppm(iim*jjp1,llm,nqtot)
    63   REAL fluxwppm(iim,jjp1,llm)
    64   REAL apppm(llmp1), bpppm(llmp1)
    65   LOGICAL dum,fill
    66   DATA fill/.true./
    67   DATA dum/.true./
    68 
    69   integer,save :: countcfl=0
    70   real cflx(ip1jmp1,llm)
    71   real cfly(ip1jm,llm)
    72   real cflz(ip1jmp1,llm)
    73   real, save :: cflxmax(llm),cflymax(llm),cflzmax(llm)
    74 
    75   IF(iadvtr.EQ.0) THEN
    76      pbaruc(:,:)=0
    77      pbarvc(:,:)=0
    78   ENDIF
    79 
    80   !   accumulation des flux de masse horizontaux
    81   DO l=1,llm
    82      DO ij = 1,ip1jmp1
    83         pbaruc(ij,l) = pbaruc(ij,l) + pbaru(ij,l)
    84      ENDDO
    85      DO ij = 1,ip1jm
    86         pbarvc(ij,l) = pbarvc(ij,l) + pbarv(ij,l)
    87      ENDDO
    88   ENDDO
    89 
    90   !   selection de la masse instantannee des mailles avant le transport.
    91   IF(iadvtr.EQ.0) THEN
    92 
     3#define DEBUG_IO
     4#undef DEBUG_IO
     5SUBROUTINE advtrac(pbaru, pbarv, p, masse,q,iapptrac,teta, flxw, pk)
     6   !     Auteur :  F. Hourdin
     7   !
     8   !     Modif. P. Le Van     (20/12/97)
     9   !            F. Codron     (10/99)
     10   !            D. Le Croller (07/2001)
     11   !            M.A Filiberti (04/2002)
     12   !
     13   USE infotrac,     ONLY: nqtot, tracers, isoCheck
     14   USE control_mod,  ONLY: iapp_tracvl, day_step
     15   USE comconst_mod, ONLY: dtvr
     16
     17   IMPLICIT NONE
     18   !
     19   include "dimensions.h"
     20   include "paramet.h"
     21   include "comdissip.h"
     22   include "comgeom2.h"
     23   include "description.h"
     24   include "iniprint.h"
     25
     26   !---------------------------------------------------------------------------
     27   !     Arguments
     28   !---------------------------------------------------------------------------
     29   INTEGER, INTENT(OUT) :: iapptrac
     30   REAL, INTENT(IN) :: pbaru(ip1jmp1,llm)
     31   REAL, INTENT(IN) :: pbarv(ip1jm,  llm)
     32   REAL, INTENT(INOUT) ::  q(ip1jmp1,llm,nqtot)
     33   REAL, INTENT(IN) :: masse(ip1jmp1,llm)
     34   REAL, INTENT(IN) ::     p(ip1jmp1,llmp1 )
     35   REAL, INTENT(IN) ::  teta(ip1jmp1,llm)
     36   REAL, INTENT(IN) ::    pk(ip1jmp1,llm)
     37   REAL, INTENT(OUT) :: flxw(ip1jmp1,llm)
     38   !---------------------------------------------------------------------------
     39   !     Ajout PPM
     40   !---------------------------------------------------------------------------
     41   REAL :: massebx(ip1jmp1,llm), masseby(ip1jm,llm)
     42   !---------------------------------------------------------------------------
     43   !     Variables locales
     44   !---------------------------------------------------------------------------
     45   INTEGER :: ij, l, iq, iadv
     46!   REAL(KIND=KIND(1.d0)) :: t_initial, t_final, tps_cpu
     47   REAL :: zdp(ip1jmp1), zdpmin, zdpmax
     48   INTEGER, SAVE :: iadvtr=0
     49   REAL, DIMENSION(ip1jmp1,llm) :: pbaruc, pbarug, massem, wg
     50   REAL, DIMENSION(ip1jm,  llm) :: pbarvc, pbarvg
     51   EXTERNAL  minmax
     52   SAVE massem, pbaruc, pbarvc
     53   !---------------------------------------------------------------------------
     54   !     Rajouts pour PPM
     55   !---------------------------------------------------------------------------
     56   INTEGER indice, n
     57   REAL :: dtbon                       ! Pas de temps adaptatif pour que CFL<1
     58   REAL :: CFLmaxz, aaa, bbb           ! CFL maximum
     59   REAL, DIMENSION(iim,jjp1,llm) :: unatppm, vnatppm, fluxwppm
     60   REAL ::    qppm(iim*jjp1,llm,nqtot)
     61   REAL ::   psppm(iim,jjp1)           ! pression  au sol
     62   REAL, DIMENSION(llmp1) :: apppm, bpppm
     63   LOGICAL, SAVE :: dum=.TRUE., fill=.TRUE.
     64
     65   INTEGER, SAVE :: countcfl=0
     66   REAL, DIMENSION(ip1jmp1,llm) :: cflx, cflz
     67   REAL, DIMENSION(ip1jm  ,llm) :: cfly
     68   REAL, DIMENSION(llm), SAVE :: cflxmax, cflymax, cflzmax
     69
     70   IF(iadvtr == 0) THEN
     71      pbaruc(:,:)=0
     72      pbarvc(:,:)=0
     73   END IF
     74
     75   !--- Accumulation des flux de masse horizontaux
     76   DO l=1,llm
     77      DO ij = 1,ip1jmp1
     78         pbaruc(ij,l) = pbaruc(ij,l) + pbaru(ij,l)
     79      END DO
     80      DO ij = 1,ip1jm
     81         pbarvc(ij,l) = pbarvc(ij,l) + pbarv(ij,l)
     82      END DO
     83   END DO
     84
     85   !--- Selection de la masse instantannee des mailles avant le transport.
     86   IF(iadvtr == 0) THEN
    9387     CALL SCOPY(ip1jmp1*llm,masse,1,massem,1)
    94      !cc         CALL filtreg ( massem ,jjp1, llm,-2, 2, .TRUE., 1 )
    95      !
    96   ENDIF
    97 
    98   iadvtr   = iadvtr+1
    99   iapptrac = iadvtr
    100 
    101 
    102   !   Test pour savoir si on advecte a ce pas de temps
    103   IF ( iadvtr.EQ.iapp_tracvl ) THEN
    104 
    105      !c   ..  Modif P.Le Van  ( 20/12/97 )  ....
    106      !c
    107 
    108      !   traitement des flux de masse avant advection.
    109      !     1. calcul de w
    110      !     2. groupement des mailles pres du pole.
    111 
    112      CALL groupe( massem, pbaruc,pbarvc, pbarug,pbarvg,wg )
    113 
    114      ! ... Flux de masse diaganostiques traceurs
    115      flxw = wg / REAL(iapp_tracvl)
    116 
    117      !  test sur l'eventuelle creation de valeurs negatives de la masse
    118      DO l=1,llm-1
    119         DO ij = iip2+1,ip1jm
    120            zdp(ij) =    pbarug(ij-1,l)   - pbarug(ij,l) &
    121                 - pbarvg(ij-iip1,l) + pbarvg(ij,l) &
    122                 +       wg(ij,l+1)  - wg(ij,l)
    123         ENDDO
    124         CALL SCOPY( jjm -1 ,zdp(iip1+iip1),iip1,zdp(iip2),iip1 )
    125         DO ij = iip2,ip1jm
    126            zdp(ij)= zdp(ij)*dtvr/ massem(ij,l)
    127         ENDDO
    128 
    129 
    130         CALL minmax ( ip1jm-iip1, zdp(iip2), zdpmin,zdpmax )
    131 
    132         IF(MAX(ABS(zdpmin),ABS(zdpmax)).GT.0.5) THEN
    133            PRINT*,'WARNING DP/P l=',l,'  MIN:',zdpmin, &
    134                 '   MAX:', zdpmax
    135         ENDIF
    136 
    137      ENDDO
    138 
    139 
    140      !-------------------------------------------------------------------
    141      ! Calcul des criteres CFL en X, Y et Z
    142      !-------------------------------------------------------------------
    143 
    144      if (countcfl == 0. ) then
    145         cflxmax(:)=0.
    146         cflymax(:)=0.
    147         cflzmax(:)=0.
    148      endif
    149 
    150      countcfl=countcfl+iapp_tracvl
    151      cflx(:,:)=0.
    152      cfly(:,:)=0.
    153      cflz(:,:)=0.
    154      do l=1,llm
    155         do ij=iip2,ip1jm-1
    156            if (pbarug(ij,l)>=0.) then
    157               cflx(ij,l)=pbarug(ij,l)*dtvr/masse(ij,l)
    158            else
    159               cflx(ij,l)=-pbarug(ij,l)*dtvr/masse(ij+1,l)
    160            endif
    161         enddo
    162      enddo
    163      do l=1,llm
    164         do ij=iip2,ip1jm-1,iip1
    165            cflx(ij+iip1,l)=cflx(ij,l)
    166         enddo
    167      enddo
    168 
    169      do l=1,llm
    170         do ij=1,ip1jm
    171            if (pbarvg(ij,l)>=0.) then
    172               cfly(ij,l)=pbarvg(ij,l)*dtvr/masse(ij,l)
    173            else
    174               cfly(ij,l)=-pbarvg(ij,l)*dtvr/masse(ij+iip1,l)
    175            endif
    176         enddo
    177      enddo
    178 
    179      do l=2,llm
    180         do ij=1,ip1jm
    181            if (wg(ij,l)>=0.) then
    182               cflz(ij,l)=wg(ij,l)*dtvr/masse(ij,l)
    183            else
    184               cflz(ij,l)=-wg(ij,l)*dtvr/masse(ij,l-1)
    185            endif
    186         enddo
    187      enddo
    188 
    189      do l=1,llm
    190         cflxmax(l)=max(cflxmax(l),maxval(cflx(:,l)))
    191         cflymax(l)=max(cflymax(l),maxval(cfly(:,l)))
    192         cflzmax(l)=max(cflzmax(l),maxval(cflz(:,l)))
    193      enddo
    194 
    195 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    196      ! Par defaut, on sort le diagnostic des CFL tous les jours.
    197      ! Si on veut le sortir a chaque pas d'advection en cas de plantage
    198      !     if (countcfl==iapp_tracvl) then
    199 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    200      if (countcfl==day_step) then
    201         do l=1,llm
    202            write(lunout,*) 'L, CFL[xyz]max:', l, cflxmax(l), cflymax(l), &
    203                 cflzmax(l)
    204         enddo
    205         countcfl=0
    206      endif
    207 
    208      !-------------------------------------------------------------------
    209      !   Advection proprement dite (Modification Le Croller (07/2001)
    210      !-------------------------------------------------------------------
    211 
    212      !----------------------------------------------------
    213      !        Calcul des moyennes basées sur la masse
    214      !----------------------------------------------------
    215      call massbar(massem,massebx,masseby)         
    216 
    217      !-----------------------------------------------------------
    218      !     Appel des sous programmes d'advection
    219      !-----------------------------------------------------------
    220 
    221      if (ok_iso_verif) then
    222            write(*,*) 'advtrac 227'
    223            call check_isotopes_seq(q,ip1jmp1,'advtrac 162')
    224      endif !if (ok_iso_verif) then
    225 
    226      do iq=1,nqperes
    227         !        call clock(t_initial)
    228         if(iadv(iq) == 0) cycle
    229         !   ----------------------------------------------------------------
    230         !   Schema de Van Leer I MUSCL
    231         !   ----------------------------------------------------------------
    232         if(iadv(iq).eq.10) THEN
    233            ! CRisi: on fait passer tout q pour avoir acces aux fils
    234            
    235            !write(*,*) 'advtrac 239: iq,q(1721,19,:)=',iq,q(1721,19,:)     
    236            call vlsplt(q,2.,massem,wg,pbarug,pbarvg,dtvr,iq)
    237            
    238            !   ----------------------------------------------------------------
    239            !   Schema "pseudo amont" + test sur humidite specifique
    240            !    pour la vapeur d'eau. F. Codron
    241            !   ----------------------------------------------------------------
    242         else if(iadv(iq).eq.14) then
    243            !
    244            !write(*,*) 'advtrac 248: iq,q(1721,19,:)=',iq,q(1721,19,:)
    245            CALL vlspltqs( q, 2., massem, wg , &
    246                 pbarug,pbarvg,dtvr,p,pk,teta,iq)
    247            
    248            !   ----------------------------------------------------------------
    249            !   Schema de Frederic Hourdin
    250            !   ----------------------------------------------------------------
    251         else if(iadv(iq).eq.12) then
    252            !            Pas de temps adaptatif
    253            call adaptdt(iadv(iq),dtbon,n,pbarug,massem)
    254            if (n.GT.1) then
    255               write(*,*) 'WARNING horizontal dt=',dtbon,'dtvr=', &
    256                    dtvr,'n=',n
    257            endif
    258            do indice=1,n
    259               call advn(q(1,1,iq),massem,wg,pbarug,pbarvg,dtbon,1)
    260            end do
    261         else if(iadv(iq).eq.13) then
    262            !            Pas de temps adaptatif
    263            call adaptdt(iadv(iq),dtbon,n,pbarug,massem)
    264            if (n.GT.1) then
    265               write(*,*) 'WARNING horizontal dt=',dtbon,'dtvr=', &
    266                    dtvr,'n=',n
    267            endif
    268            do indice=1,n
    269               call advn(q(1,1,iq),massem,wg,pbarug,pbarvg,dtbon,2)
    270            end do
    271            !   ----------------------------------------------------------------
    272            !   Schema de pente SLOPES
    273            !   ----------------------------------------------------------------
    274         else if (iadv(iq).eq.20) then
    275            call pentes_ini (q(1,1,iq),wg,massem,pbarug,pbarvg,0)
    276 
    277            !   ----------------------------------------------------------------
    278            !   Schema de Prather
    279            !   ----------------------------------------------------------------
    280         else if (iadv(iq).eq.30) then
    281            !            Pas de temps adaptatif
    282            call adaptdt(iadv(iq),dtbon,n,pbarug,massem)
    283            if (n.GT.1) then
    284               write(*,*) 'WARNING horizontal dt=',dtbon,'dtvr=', &
    285                    dtvr,'n=',n
    286            endif
    287            call  prather(q(1,1,iq),wg,massem,pbarug,pbarvg, &
    288                 n,dtbon)
    289 
    290            !   ----------------------------------------------------------------
    291            !   Schemas PPM Lin et Rood
    292            !   ----------------------------------------------------------------
    293         else if (iadv(iq).eq.11.OR.(iadv(iq).GE.16.AND. &
    294              iadv(iq).LE.18)) then
    295 
    296            !        Test sur le flux horizontal
    297            !        Pas de temps adaptatif
    298            call adaptdt(iadv(iq),dtbon,n,pbarug,massem)
    299            if (n.GT.1) then
    300               write(*,*) 'WARNING horizontal dt=',dtbon,'dtvr=', &
    301                    dtvr,'n=',n
    302            endif
    303            !        Test sur le flux vertical
    304            CFLmaxz=0.
    305            do l=2,llm
    306               do ij=iip2,ip1jm
    307                  aaa=wg(ij,l)*dtvr/massem(ij,l)
    308                  CFLmaxz=max(CFLmaxz,aaa)
    309                  bbb=-wg(ij,l)*dtvr/massem(ij,l-1)
    310                  CFLmaxz=max(CFLmaxz,bbb)
    311               enddo
    312            enddo
    313            if (CFLmaxz.GE.1) then
    314               write(*,*) 'WARNING vertical','CFLmaxz=', CFLmaxz
    315            endif
    316 
    317            !-----------------------------------------------------------
    318            !        Ss-prg interface LMDZ.4->PPM3d
    319            !-----------------------------------------------------------
    320 
    321            call interpre(q(1,1,iq),qppm(1,1,iq),wg,fluxwppm,massem, &
    322                 apppm,bpppm,massebx,masseby,pbarug,pbarvg, &
    323                 unatppm,vnatppm,psppm)
    324 
    325            do indice=1,n
    326               !----------------------------------------------------------------
    327               !                         VL (version PPM) horiz. et PPM vert.
    328               !----------------------------------------------------------------
    329               if (iadv(iq).eq.11) then
    330                  !                  Ss-prg PPM3d de Lin
    331                  call ppm3d(1,qppm(1,1,iq), &
    332                       psppm,psppm, &
    333                       unatppm,vnatppm,fluxwppm,dtbon,2,2,2,1, &
    334                       iim,jjp1,2,llm,apppm,bpppm,0.01,6400000, &
    335                       fill,dum,220.)
    336 
    337                  !-------------------------------------------------------------
    338                  !                           Monotonic PPM
    339                  !-------------------------------------------------------------
    340               else if (iadv(iq).eq.16) then
    341                  !                  Ss-prg PPM3d de Lin
    342                  call ppm3d(1,qppm(1,1,iq), &
    343                       psppm,psppm, &
    344                       unatppm,vnatppm,fluxwppm,dtbon,3,3,3,1, &
    345                       iim,jjp1,2,llm,apppm,bpppm,0.01,6400000, &
    346                       fill,dum,220.)
    347                  !-------------------------------------------------------------
    348 
    349                  !-------------------------------------------------------------
    350                  !                           Semi Monotonic PPM
    351                  !-------------------------------------------------------------
    352               else if (iadv(iq).eq.17) then
    353                  !                  Ss-prg PPM3d de Lin
    354                  call ppm3d(1,qppm(1,1,iq), &
    355                       psppm,psppm, &
    356                       unatppm,vnatppm,fluxwppm,dtbon,4,4,4,1, &
    357                       iim,jjp1,2,llm,apppm,bpppm,0.01,6400000, &
    358                       fill,dum,220.)
    359                  !-------------------------------------------------------------
    360 
    361                  !-------------------------------------------------------------
    362                  !                         Positive Definite PPM
    363                  !-------------------------------------------------------------
    364               else if (iadv(iq).eq.18) then
    365                  !                  Ss-prg PPM3d de Lin
    366                  call ppm3d(1,qppm(1,1,iq), &
    367                       psppm,psppm, &
    368                       unatppm,vnatppm,fluxwppm,dtbon,5,5,5,1, &
    369                       iim,jjp1,2,llm,apppm,bpppm,0.01,6400000, &
    370                       fill,dum,220.)
    371                  !-------------------------------------------------------------
    372               endif
    373            enddo
    374            !-----------------------------------------------------------------
    375            !               Ss-prg interface PPM3d-LMDZ.4
    376            !-----------------------------------------------------------------
    377            call interpost(q(1,1,iq),qppm(1,1,iq))
    378         endif
    379         !----------------------------------------------------------------------
    380 
    381         !-----------------------------------------------------------------
    382         ! On impose une seule valeur du traceur au pôle Sud j=jjm+1=jjp1
    383         ! et Nord j=1
    384         !-----------------------------------------------------------------
    385 
    386         !                  call traceurpole(q(1,1,iq),massem)
    387 
    388         ! calcul du temps cpu pour un schema donne
    389 
    390         !                  call clock(t_final)
    391         !ym                  tps_cpu=t_final-t_initial
    392         !ym                  cpuadv(iq)=cpuadv(iq)+tps_cpu
    393 
    394      end DO
    395 
    396      if (ok_iso_verif) then
    397            write(*,*) 'advtrac 402'
    398            call check_isotopes_seq(q,ip1jmp1,'advtrac 397')
    399      endif !if (ok_iso_verif) then
    400 
    401      !------------------------------------------------------------------
    402      !   on reinitialise a zero les flux de masse cumules
    403      !---------------------------------------------------
    404      iadvtr=0
    405 
    406   ENDIF ! if iadvtr.EQ.iapp_tracvl
     88   ! CALL filtreg ( massem ,jjp1, llm,-2, 2, .TRUE., 1 )
     89   END IF
     90
     91   iadvtr   = iadvtr+1
     92   iapptrac = iadvtr
     93
     94   !--- Test pour savoir si on advecte a ce pas de temps
     95   IF(iadvtr /= iapp_tracvl) RETURN
     96
     97   !   ..  Modif P.Le Van  ( 20/12/97 )  ....
     98   !
     99   !   traitement des flux de masse avant advection.
     100   !       1. calcul de w
     101   !       2. groupement des mailles pres du pole.
     102
     103   CALL groupe(massem, pbaruc, pbarvc, pbarug, pbarvg, wg)
     104
     105   !--- Flux de masse diaganostiques traceurs
     106   flxw = wg / REAL(iapp_tracvl)
     107
     108   !--- Test sur l'eventuelle creation de valeurs negatives de la masse
     109   DO l=1,llm-1
     110      DO ij = iip2+1,ip1jm
     111         zdp(ij) = pbarug(ij-1,l)    - pbarug(ij,l) &
     112                 - pbarvg(ij-iip1,l) + pbarvg(ij,l) &
     113                 +     wg(ij,l+1)    -     wg(ij,l)
     114      END DO
     115! ym  ---> pourquoi jjm-1 et non jjm ? a cause du pole ?
     116      CALL SCOPY( jjm -1 ,zdp(iip1+iip1),iip1,zdp(iip2),iip1 )
     117      DO ij = iip2,ip1jm
     118         zdp(ij)= zdp(ij)*dtvr/ massem(ij,l)
     119      END DO
     120
     121      CALL minmax ( ip1jm-iip1, zdp(iip2), zdpmin,zdpmax )
     122
     123      IF(MAX(ABS(zdpmin),ABS(zdpmax)) > 0.5) &
     124         WRITE(*,*)'WARNING DP/P l=',l,'  MIN:',zdpmin,' MAX:', zdpmax
     125
     126   END DO
     127
     128   !-------------------------------------------------------------------------
     129   ! Calcul des criteres CFL en X, Y et Z
     130   !-------------------------------------------------------------------------
     131   IF(countcfl == 0. ) then
     132      cflxmax(:)=0.
     133      cflymax(:)=0.
     134      cflzmax(:)=0.
     135   END IF
     136
     137   countcfl=countcfl+iapp_tracvl
     138   cflx(:,:)=0.
     139   cfly(:,:)=0.
     140   cflz(:,:)=0.
     141   DO l=1,llm
     142      DO ij=iip2,ip1jm-1
     143         IF(pbarug(ij,l)>=0.) then
     144            cflx(ij,l)=pbarug(ij,l)*dtvr/masse(ij,l)
     145         ELSE
     146            cflx(ij,l)=-pbarug(ij,l)*dtvr/masse(ij+1,l)
     147         END IF
     148      END DO
     149   END DO
     150
     151   DO l=1,llm
     152      DO ij=iip2,ip1jm-1,iip1
     153         cflx(ij+iip1,l)=cflx(ij,l)
     154      END DO
     155   END DO
     156
     157   DO l=1,llm
     158      DO ij=1,ip1jm
     159         IF(pbarvg(ij,l)>=0.) then
     160            cfly(ij,l)=pbarvg(ij,l)*dtvr/masse(ij,l)
     161         ELSE
     162            cfly(ij,l)=-pbarvg(ij,l)*dtvr/masse(ij+iip1,l)
     163         END IF
     164      END DO
     165   END DO
     166
     167   DO l=2,llm
     168      DO ij=1,ip1jm
     169         IF(wg(ij,l) >= 0.) THEN
     170            cflz(ij,l)=wg(ij,l)*dtvr/masse(ij,l)
     171         ELSE
     172            cflz(ij,l)=-wg(ij,l)*dtvr/masse(ij,l-1)
     173         END IF
     174      END DO
     175   END DO
     176
     177   DO l=1,llm
     178      cflxmax(l)=max(cflxmax(l),maxval(cflx(:,l)))
     179      cflymax(l)=max(cflymax(l),maxval(cfly(:,l)))
     180      cflzmax(l)=max(cflzmax(l),maxval(cflz(:,l)))
     181   END DO
     182
     183   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
     184   ! Par defaut, on sort le diagnostic des CFL tous les jours.
     185   ! Si on veut le sortir a chaque pas d'advection en cas de plantage
     186   !       IF(countcfl==iapp_tracvl) then
     187   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
     188   IF(countcfl==day_step) then
     189      DO l=1,llm
     190         WRITE(lunout,*) 'L, CFL[xyz]max:', l, cflxmax(l), cflymax(l), cflzmax(l)
     191      END DO
     192      countcfl=0
     193   END IF
     194
     195   !---------------------------------------------------------------------------
     196   !   Advection proprement dite (Modification Le Croller (07/2001)
     197   !---------------------------------------------------------------------------
     198
     199   !---------------------------------------------------------------------------
     200   !   Calcul des moyennes basees sur la masse
     201   !---------------------------------------------------------------------------
     202   CALL massbar(massem,massebx,masseby)
     203
     204#ifdef DEBUG_IO   
     205   CALL WriteField_u('massem',massem)
     206   CALL WriteField_u('wg',wg)
     207   CALL WriteField_u('pbarug',pbarug)
     208   CALL WriteField_v('pbarvg',pbarvg)
     209   CALL WriteField_u('p_tmp',p)
     210   CALL WriteField_u('pk_tmp',pk)
     211   CALL WriteField_u('teta_tmp',teta)
     212   DO iq=1,nqtot
     213      CALL WriteField_u('q_adv'//trim(int2str(iq)),q(:,:,iq))
     214   END DO
     215#endif
     216
     217   IF(isoCheck) WRITE(*,*) 'advtrac 227'
     218   CALL check_isotopes_seq(q,ip1jmp1,'advtrac 162')
     219
     220   !-------------------------------------------------------------------------
     221   !       Appel des sous programmes d'advection
     222   !-------------------------------------------------------------------------
     223   DO iq = 1, nqtot
     224!     CALL clock(t_initial)
     225      IF(tracers(iq)%parent /= 'air') CYCLE
     226      iadv = tracers(iq)%iadv
     227      !-----------------------------------------------------------------------
     228      SELECT CASE(iadv)
     229      !-----------------------------------------------------------------------
     230         CASE(0); CYCLE
     231         !--------------------------------------------------------------------
     232         CASE(10)  !--- Schema de Van Leer I MUSCL
     233         !--------------------------------------------------------------------
     234!           WRITE(*,*) 'advtrac 239: iq,q(1721,19,:)=',iq,q(1721,19,:)     
     235            CALL vlsplt(q,2.,massem,wg,pbarug,pbarvg,dtvr,iq)
     236
     237         !--------------------------------------------------------------------
     238         CASE(14)  !--- Schema "pseuDO amont" + test sur humidite specifique
     239                   !--- pour la vapeur d'eau. F. Codron
     240         !--------------------------------------------------------------------
     241!           WRITE(*,*) 'advtrac 248: iq,q(1721,19,:)=',iq,q(1721,19,:)
     242            CALL vlspltqs(q,2.,massem,wg,pbarug,pbarvg,dtvr,p,pk,teta,iq)
     243
     244         !--------------------------------------------------------------------
     245         CASE(12)  !--- Schema de Frederic Hourdin
     246         !--------------------------------------------------------------------
     247            CALL adaptdt(iadv,dtbon,n,pbarug,massem)   ! pas de temps adaptatif
     248            IF(n > 1) WRITE(*,*) 'WARNING horizontal dt=',dtbon,'dtvr=',dtvr,'n=',n
     249            DO indice=1,n
     250              CALL advn(q(1,1,iq),massem,wg,pbarug,pbarvg,dtbon,1)
     251            END DO
     252
     253         !--------------------------------------------------------------------
     254         CASE(13)  !--- Pas de temps adaptatif
     255         !--------------------------------------------------------------------
     256            CALL adaptdt(iadv,dtbon,n,pbarug,massem)
     257            IF(n > 1) WRITE(*,*) 'WARNING horizontal dt=',dtbon,'dtvr=',dtvr,'n=',n
     258            DO indice=1,n
     259               CALL advn(q(1,1,iq),massem,wg,pbarug,pbarvg,dtbon,2)
     260            END DO
     261
     262         !--------------------------------------------------------------------
     263         CASE(20)  !--- Schema de pente SLOPES
     264         !--------------------------------------------------------------------
     265            CALL pentes_ini (q(1,1,iq),wg,massem,pbarug,pbarvg,0)
     266
     267         !--------------------------------------------------------------------
     268         CASE(30)  !--- Schema de Prather
     269         !--------------------------------------------------------------------
     270            ! Pas de temps adaptatif
     271            CALL adaptdt(iadv,dtbon,n,pbarug,massem)
     272            IF(n > 1) WRITE(*,*) 'WARNING horizontal dt=',dtbon,'dtvr=',dtvr,'n=',n
     273            CALL prather(q(1,1,iq),wg,massem,pbarug,pbarvg,n,dtbon)
     274
     275         !--------------------------------------------------------------------
     276         CASE(11,16,17,18)   !--- Schemas PPM Lin et Rood
     277         !--------------------------------------------------------------------
     278            ! Test sur le flux horizontal
     279            CALL adaptdt(iadv,dtbon,n,pbarug,massem)   ! pas de temps adaptatif
     280            IF(n > 1) WRITE(*,*) 'WARNING horizontal dt=',dtbon,'dtvr=',dtvr,'n=',n
     281            ! Test sur le flux vertical
     282            CFLmaxz=0.
     283            DO l=2,llm
     284               DO ij=iip2,ip1jm
     285                  aaa=wg(ij,l)*dtvr/massem(ij,l)
     286                  CFLmaxz=max(CFLmaxz,aaa)
     287                  bbb=-wg(ij,l)*dtvr/massem(ij,l-1)
     288                  CFLmaxz=max(CFLmaxz,bbb)
     289               END DO
     290            END DO
     291            IF(CFLmaxz.GE.1) WRITE(*,*) 'WARNING vertical','CFLmaxz=', CFLmaxz
     292            !----------------------------------------------------------------
     293            !     Ss-prg interface LMDZ.4->PPM3d (ss-prg de Lin)
     294            !----------------------------------------------------------------
     295            CALL interpre(q(1,1,iq),qppm(1,1,iq),wg,fluxwppm,massem, &
     296                 apppm,bpppm,massebx,masseby,pbarug,pbarvg, &
     297                 unatppm,vnatppm,psppm)
     298
     299            !----------------------------------------------------------------
     300            DO indice=1,n     !--- VL (version PPM) horiz. et PPM vert.
     301            !----------------------------------------------------------------
     302               SELECT CASE(iadv)
     303                  !----------------------------------------------------------
     304                  CASE(11)
     305                  !----------------------------------------------------------
     306                     CALL ppm3d(1,qppm(1,1,iq),psppm,psppm,unatppm,vnatppm,fluxwppm,dtbon, &
     307                                2,2,2,1,iim,jjp1,2,llm,apppm,bpppm,0.01,6400000,fill,dum,220.)
     308                  !----------------------------------------------------------
     309                  CASE(16) !--- Monotonic PPM
     310                  !----------------------------------------------------------
     311                     CALL ppm3d(1,qppm(1,1,iq),psppm,psppm,unatppm,vnatppm,fluxwppm,dtbon, &
     312                                3,3,3,1,iim,jjp1,2,llm,apppm,bpppm,0.01,6400000,fill,dum,220.)
     313                  !----------------------------------------------------------
     314                  CASE(17) !--- Semi monotonic PPM
     315                  !----------------------------------------------------------
     316                     CALL ppm3d(1,qppm(1,1,iq),psppm,psppm,unatppm,vnatppm,fluxwppm,dtbon, &
     317                                4,4,4,1,iim,jjp1,2,llm,apppm,bpppm,0.01,6400000, fill,dum,220.)
     318                  !----------------------------------------------------------
     319                  CASE(18) !--- Positive Definite PPM
     320                  !----------------------------------------------------------
     321                     CALL ppm3d(1,qppm(1,1,iq),psppm,psppm,unatppm,vnatppm,fluxwppm,dtbon, &
     322                                5,5,5,1,iim,jjp1,2,llm,apppm,bpppm,0.01,6400000,fill,dum,220.)
     323               END SELECT
     324            !----------------------------------------------------------------
     325            END DO
     326            !----------------------------------------------------------------
     327            !     Ss-prg interface PPM3d-LMDZ.4
     328            !----------------------------------------------------------------
     329            CALL interpost(q(1,1,iq),qppm(1,1,iq))
     330      !----------------------------------------------------------------------
     331      END SELECT
     332      !----------------------------------------------------------------------
     333
     334      !----------------------------------------------------------------------
     335      ! On impose une seule valeur du traceur au pole Sud j=jjm+1=jjp1 et Nord j=1
     336      !----------------------------------------------------------------------
     337      !  CALL traceurpole(q(1,1,iq),massem)
     338
     339      !--- Calcul du temps cpu pour un schema donne
     340      !  CALL clock(t_final)
     341      !ym  tps_cpu=t_final-t_initial
     342      !ym  cpuadv(iq)=cpuadv(iq)+tps_cpu
     343
     344   END DO
     345
     346   IF(isoCheck) WRITE(*,*) 'advtrac 402'
     347   CALL check_isotopes_seq(q,ip1jmp1,'advtrac 397')
     348
     349   !-------------------------------------------------------------------------
     350   !   on reinitialise a zero les flux de masse cumules
     351   !-------------------------------------------------------------------------
     352   iadvtr=0
    407353
    408354END SUBROUTINE advtrac
Note: See TracChangeset for help on using the changeset viewer.