source: LMDZ6/trunk/libf/dyn3d/vlspltqs.F90 @ 5274

Last change on this file since 5274 was 5272, checked in by abarral, 8 months ago

Turn paramet.h into a module

  • Property copyright set to
    Name of program: LMDZ
    Creation date: 1984
    Version: LMDZ5
    License: CeCILL version 2
    Holder: Laboratoire de m\'et\'eorologie dynamique, CNRS, UMR 8539
    See the license file in the root directory
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 23.3 KB
RevLine 
[5246]1!
2! $Id: vlspltqs.F90 5272 2024-10-24 15:53:15Z abarral $
3!
4 SUBROUTINE vlspltqs ( q,pente_max,masse,w,pbaru,pbarv,pdt, &
5         p,pk,teta,iq             )
6   USE infotrac, ONLY: nqtot,tracers
7  !
8  ! Auteurs:   P.Le Van, F.Hourdin, F.Forget, F.Codron
9  !
10  !    ********************************************************************
11  !      Shema  d'advection " pseudo amont " .
12  !  + test sur humidite specifique: Q advecte< Qsat aval
13  !               (F. Codron, 10/99)
14  !    ********************************************************************
15  ! q,pbaru,pbarv,w sont des arguments d'entree  pour le s-pg ....
16  !
17  ! pente_max facteur de limitation des pentes: 2 en general
18  !                                            0 pour un schema amont
19  ! pbaru,pbarv,w flux de masse en u ,v ,w
20  ! pdt pas de temps
21  !
22  ! teta temperature potentielle, p pression aux interfaces,
23  ! pk exner au milieu des couches necessaire pour calculer Qsat
24  !   --------------------------------------------------------------------
[524]25
[5246]26  USE comconst_mod, ONLY: cpp
27  USE logic_mod, ONLY: adv_qsat_liq
[5271]28  USE dimensions_mod, ONLY: iim, jjm, llm, ndm
[5272]29USE paramet_mod_h, ONLY: iip1, iip2, iip3, jjp1, llmp1, llmp2, llmm1, kftd, ip1jm, ip1jmp1, &
30          ip1jmi1, ijp1llm, ijmllm, mvar, jcfil, jcfllm
[5271]31IMPLICIT NONE
[5246]32  !
[5271]33
[524]34
[5272]35
[5246]36  !
37  !   Arguments:
38  !   ----------
39  REAL :: masse(ip1jmp1,llm),pente_max
40  REAL :: pbaru( ip1jmp1,llm ),pbarv( ip1jm,llm)
41  REAL :: q(ip1jmp1,llm,nqtot)
42  REAL :: w(ip1jmp1,llm),pdt
43  REAL :: p(ip1jmp1,llmp1),teta(ip1jmp1,llm),pk(ip1jmp1,llm)
44  INTEGER :: iq ! CRisi
45  !
46  !  Local
47  !   ---------
48  !
49  INTEGER :: i,ij,l,j,ii
50  INTEGER :: ifils,iq2 ! CRisi
51  !
52  REAL :: qsat(ip1jmp1,llm)
53  REAL :: zm(ip1jmp1,llm,nqtot)
54  REAL :: mu(ip1jmp1,llm)
55  REAL :: mv(ip1jm,llm)
56  REAL :: mw(ip1jmp1,llm+1)
57  REAL :: zq(ip1jmp1,llm,nqtot)
58  REAL :: temps1,temps2,temps3
59  REAL :: zzpbar, zzw
60  LOGICAL :: testcpu
61  SAVE testcpu
62  SAVE temps1,temps2,temps3
[524]63
[5246]64  REAL :: qmin,qmax
65  DATA qmin,qmax/0.,1.e33/
66  DATA testcpu/.false./
67  DATA temps1,temps2,temps3/0.,0.,0./
[524]68
[5246]69  !--pour rapport de melange saturant--
[524]70
[5246]71  REAL :: rtt,retv,r2es,r3les,r3ies,r4les,r4ies,play
72  REAL :: ptarg,pdelarg,foeew,zdelta
73  REAL :: tempe(ip1jmp1)
[524]74
[5246]75  !    fonction psat(T)
[524]76
[5246]77   FOEEW ( PTARG,PDELARG ) = EXP ( &
78         (R3LES*(1.-PDELARG)+R3IES*PDELARG) * (PTARG-RTT) &
79         / (PTARG-(R4LES*(1.-PDELARG)+R4IES*PDELARG)) )
[524]80
[5246]81    r2es  = 380.11733
82    r3les = 17.269
83    r3ies = 21.875
84    r4les = 35.86
85    r4ies = 7.66
86    retv = 0.6077667
87    rtt  = 273.16
[524]88
[5246]89  !-- Calcul de Qsat en chaque point
90  !-- approximation: au milieu des couches play(l)=(p(l)+p(l+1))/2
91  !   pour eviter une exponentielle.
92    DO l = 1, llm
93     DO ij = 1, ip1jmp1
94      tempe(ij) = teta(ij,l) * pk(ij,l) /cpp
95     ENDDO
96     DO ij = 1, ip1jmp1
97      IF (adv_qsat_liq) THEN
98         zdelta = 0.
99      ELSE
100         zdelta = MAX( 0., SIGN(1., rtt - tempe(ij)) )
101      ENDIF
102      play   = 0.5*(p(ij,l)+p(ij,l+1))
103      qsat(ij,l) = MIN(0.5, r2es* FOEEW(tempe(ij),zdelta) / play )
104      qsat(ij,l) = qsat(ij,l) / ( 1. - retv * qsat(ij,l) )
105     ENDDO
106    ENDDO
[524]107
[5246]108   ! PRINT*,'Debut vlsplt version debug sans vlyqs'
[524]109
[5246]110    zzpbar = 0.5 * pdt
111    zzw    = pdt
112  DO l=1,llm
113    DO ij = iip2,ip1jm
114        mu(ij,l)=pbaru(ij,l) * zzpbar
115     ENDDO
116     DO ij=1,ip1jm
117        mv(ij,l)=pbarv(ij,l) * zzpbar
118     ENDDO
119     DO ij=1,ip1jmp1
120        mw(ij,l)=w(ij,l) * zzw
121     ENDDO
122  ENDDO
[524]123
[5246]124  DO ij=1,ip1jmp1
125     mw(ij,llm+1)=0.
126  ENDDO
[524]127
[5246]128  CALL SCOPY(ijp1llm,q(1,1,iq),1,zq(1,1,iq),1)
129  CALL SCOPY(ijp1llm,masse,1,zm(1,1,iq),1)
130  do ifils=1,tracers(iq)%nqDescen
131    iq2=tracers(iq)%iqDescen(ifils)
132    CALL SCOPY(ijp1llm,q(1,1,iq2),1,zq(1,1,iq2),1)
133  enddo
[524]134
[5246]135   ! call minmaxq(zq,qmin,qmax,'avant vlxqs     ')
136  call vlxqs(zq,pente_max,zm,mu,qsat,iq)
[524]137
[5246]138  ! call minmaxq(zq,qmin,qmax,'avant vlyqs     ')
[524]139
[5246]140  call vlyqs(zq,pente_max,zm,mv,qsat,iq)
[524]141
[5246]142   ! call minmaxq(zq,qmin,qmax,'avant vlz     ')
[524]143
[5246]144  call vlz(zq,pente_max,zm,mw,iq)
[524]145
[5246]146  ! call minmaxq(zq,qmin,qmax,'avant vlyqs     ')
147  ! call minmaxq(zm,qmin,qmax,'M avant vlyqs     ')
[524]148
[5246]149  call vlyqs(zq,pente_max,zm,mv,qsat,iq)
[524]150
[5246]151  ! call minmaxq(zq,qmin,qmax,'avant vlxqs     ')
152  ! call minmaxq(zm,qmin,qmax,'M avant vlxqs     ')
[524]153
[5246]154  call vlxqs(zq,pente_max,zm,mu,qsat,iq)
[524]155
[5246]156  ! call minmaxq(zq,qmin,qmax,'apres vlxqs     ')
157  ! call minmaxq(zm,qmin,qmax,'M apres vlxqs     ')
[524]158
[5246]159
160  DO l=1,llm
161     DO ij=1,ip1jmp1
162       q(ij,l,iq)=zq(ij,l,iq)
163     ENDDO
164     DO ij=1,ip1jm+1,iip1
165        q(ij+iim,l,iq)=q(ij,l,iq)
166     ENDDO
167  ENDDO
168  ! ! CRisi: aussi pour les fils
169  do ifils=1,tracers(iq)%nqDescen
170    iq2=tracers(iq)%iqDescen(ifils)
171    DO l=1,llm
172      DO ij=1,ip1jmp1
173        q(ij,l,iq2)=zq(ij,l,iq2)
[524]174      ENDDO
[5246]175      DO ij=1,ip1jm+1,iip1
176        q(ij+iim,l,iq2)=q(ij,l,iq2)
177      ENDDO
178    ENDDO
179  enddo
180  ! !write(*,*) 'vlspltqs 183: fin de la routine'
[524]181
[5246]182  RETURN
183END SUBROUTINE vlspltqs
184SUBROUTINE vlxqs(q,pente_max,masse,u_m,qsat,iq)
185  USE infotrac, ONLY : nqtot,tracers ! CRisi
[2270]186
[5246]187  !
188  ! Auteurs:   P.Le Van, F.Hourdin, F.Forget
189  !
190  !    ********************************************************************
191  ! Shema  d'advection " pseudo amont " .
192  !    ********************************************************************
193  !
194  !   --------------------------------------------------------------------
[5271]195  USE dimensions_mod, ONLY: iim, jjm, llm, ndm
[5272]196USE paramet_mod_h, ONLY: iip1, iip2, iip3, jjp1, llmp1, llmp2, llmm1, kftd, ip1jm, ip1jmp1, &
197          ip1jmi1, ijp1llm, ijmllm, mvar, jcfil, jcfllm
[5271]198IMPLICIT NONE
[5246]199  !
[5271]200
[5272]201
[5246]202  !
203  !
204  !   Arguments:
205  !   ----------
206  REAL :: masse(ip1jmp1,llm,nqtot),pente_max
207  REAL :: u_m( ip1jmp1,llm )
208  REAL :: q(ip1jmp1,llm,nqtot)
209  REAL :: qsat(ip1jmp1,llm)
210  INTEGER :: iq ! CRisi
211  !
212  !  Local
213  !   ---------
214  !
215  INTEGER :: ij,l,j,i,iju,ijq,indu(ip1jmp1),niju
216  INTEGER :: n0,iadvplus(ip1jmp1,llm),nl(llm)
217  !
218  REAL :: new_m,zu_m,zdum(ip1jmp1,llm)
219  REAL :: dxq(ip1jmp1,llm),dxqu(ip1jmp1)
220  REAL :: zz(ip1jmp1)
221  REAL :: adxqu(ip1jmp1),dxqmax(ip1jmp1,llm)
222  REAL :: u_mq(ip1jmp1,llm)
[524]223
[5246]224  ! ! CRisi
225  REAL :: masseq(ip1jmp1,llm,nqtot),Ratio(ip1jmp1,llm,nqtot)
226  INTEGER :: ifils,iq2 ! CRisi
[2270]227
[5246]228  Logical :: first,testcpu
229  SAVE first,testcpu
[524]230
[5246]231  REAL :: SSUM
232  REAL :: temps0,temps1,temps2,temps3,temps4,temps5
233  SAVE temps0,temps1,temps2,temps3,temps4,temps5
[524]234
235
[5246]236  DATA first,testcpu/.true.,.false./
[524]237
[5246]238  IF(first) THEN
239     temps1=0.
240     temps2=0.
241     temps3=0.
242     temps4=0.
243     temps5=0.
244     first=.false.
245  ENDIF
[524]246
[5246]247  !   calcul de la pente a droite et a gauche de la maille
[524]248
249
[5246]250  IF (pente_max.gt.-1.e-5) THEN
251  ! IF (pente_max.gt.10) THEN
[524]252
[5246]253  !   calcul des pentes avec limitation, Van Leer scheme I:
254  !   -----------------------------------------------------
[524]255
[5246]256  !   calcul de la pente aux points u
257     DO l = 1, llm
258        DO ij=iip2,ip1jm-1
259           dxqu(ij)=q(ij+1,l,iq)-q(ij,l,iq)
260        ENDDO
261        DO ij=iip1+iip1,ip1jm,iip1
262           dxqu(ij)=dxqu(ij-iim)
263           ! sigu(ij)=sigu(ij-iim)
264        ENDDO
[524]265
[5246]266        DO ij=iip2,ip1jm
267           adxqu(ij)=abs(dxqu(ij))
268        ENDDO
[524]269
[5246]270  !   calcul de la pente maximum dans la maille en valeur absolue
[524]271
[5246]272        DO ij=iip2+1,ip1jm
273           dxqmax(ij,l)=pente_max* &
274                 min(adxqu(ij-1),adxqu(ij))
275  ! limitation subtile
276  !    ,      min(adxqu(ij-1)/sigu(ij-1),adxqu(ij)/(1.-sigu(ij)))
[524]277
278
[5246]279        ENDDO
[524]280
[5246]281        DO ij=iip1+iip1,ip1jm,iip1
282           dxqmax(ij-iim,l)=dxqmax(ij,l)
283        ENDDO
284
285        DO ij=iip2+1,ip1jm
[524]286#ifdef CRAY
[5246]287           dxq(ij,l)= &
288                 cvmgp(dxqu(ij-1)+dxqu(ij),0.,dxqu(ij-1)*dxqu(ij))
[524]289#else
[5246]290           IF(dxqu(ij-1)*dxqu(ij).gt.0) THEN
291              dxq(ij,l)=dxqu(ij-1)+dxqu(ij)
292           ELSE
293  !   extremum local
294              dxq(ij,l)=0.
295           ENDIF
[524]296#endif
[5246]297           dxq(ij,l)=0.5*dxq(ij,l)
298           dxq(ij,l)= &
299                 sign(min(abs(dxq(ij,l)),dxqmax(ij,l)),dxq(ij,l))
300        ENDDO
[524]301
[5246]302     ENDDO ! l=1,llm
[524]303
[5246]304  ELSE ! (pente_max.lt.-1.e-5)
[524]305
[5246]306  !   Pentes produits:
307  !   ----------------
[524]308
[5246]309     DO l = 1, llm
310        DO ij=iip2,ip1jm-1
311           dxqu(ij)=q(ij+1,l,iq)-q(ij,l,iq)
312        ENDDO
313        DO ij=iip1+iip1,ip1jm,iip1
314           dxqu(ij)=dxqu(ij-iim)
315        ENDDO
[524]316
[5246]317        DO ij=iip2+1,ip1jm
318           zz(ij)=dxqu(ij-1)*dxqu(ij)
319           zz(ij)=zz(ij)+zz(ij)
320           IF(zz(ij).gt.0) THEN
321              dxq(ij,l)=zz(ij)/(dxqu(ij-1)+dxqu(ij))
322           ELSE
323  !   extremum local
324              dxq(ij,l)=0.
325           ENDIF
326        ENDDO
[524]327
[5246]328     ENDDO
[524]329
[5246]330  ENDIF ! (pente_max.lt.-1.e-5)
[524]331
[5246]332  !   bouclage de la pente en iip1:
333  !   -----------------------------
[524]334
[5246]335  DO l=1,llm
336     DO ij=iip1+iip1,ip1jm,iip1
337        dxq(ij-iim,l)=dxq(ij,l)
338     ENDDO
[524]339
[5246]340     DO ij=1,ip1jmp1
341        iadvplus(ij,l)=0
342     ENDDO
[524]343
[5246]344  ENDDO
[524]345
346
[5246]347  !   calcul des flux a gauche et a droite
[524]348
349#ifdef CRAY
[5246]350  !--pas encore modification sur Qsat
351  DO l=1,llm
352   DO ij=iip2,ip1jm-1
353      zdum(ij,l)=cvmgp(1.-u_m(ij,l)/masse(ij,l,iq), &
354            1.+u_m(ij,l)/masse(ij+1,l,iq), &
355            u_m(ij,l))
356      zdum(ij,l)=0.5*zdum(ij,l)
357      u_mq(ij,l)=cvmgp( &
358            q(ij,l,iq)+zdum(ij,l)*dxq(ij,l), &
359            q(ij+1,l,iq)-zdum(ij,l)*dxq(ij+1,l), &
360            u_m(ij,l))
361      u_mq(ij,l)=u_m(ij,l)*u_mq(ij,l)
362   ENDDO
363  ENDDO
[524]364#else
[5246]365  !   on cumule le flux correspondant a toutes les mailles dont la masse
366  !   au travers de la paroi pENDant le pas de temps.
367  !   le rapport de melange de l'air advecte est min(q_vanleer, Qsat_downwind)
368  DO l=1,llm
369   DO ij=iip2,ip1jm-1
370      IF (u_m(ij,l).gt.0.) THEN
371         zdum(ij,l)=1.-u_m(ij,l)/masse(ij,l,iq)
372         u_mq(ij,l)=u_m(ij,l)* &
373               min(q(ij,l,iq)+0.5*zdum(ij,l)*dxq(ij,l),qsat(ij+1,l))
374      ELSE
375         zdum(ij,l)=1.+u_m(ij,l)/masse(ij+1,l,iq)
376         u_mq(ij,l)=u_m(ij,l)* &
377               min(q(ij+1,l,iq)-0.5*zdum(ij,l)*dxq(ij+1,l),qsat(ij,l))
378      ENDIF
379   ENDDO
380  ENDDO
[524]381#endif
382
383
[5246]384  !   detection des points ou on advecte plus que la masse de la
385  !   maille
386  DO l=1,llm
387     DO ij=iip2,ip1jm-1
388        IF(zdum(ij,l).lt.0) THEN
389           iadvplus(ij,l)=1
390           u_mq(ij,l)=0.
391        ENDIF
392     ENDDO
393  ENDDO
394  DO l=1,llm
395   DO ij=iip1+iip1,ip1jm,iip1
396      iadvplus(ij,l)=iadvplus(ij-iim,l)
397   ENDDO
398  ENDDO
[524]399
400
401
[5246]402  !   traitement special pour le cas ou on advecte en longitude plus que le
403  !   contenu de la maille.
404  !   cette partie est mal vectorisee.
[524]405
[5246]406  !   pas d'influence de la pression saturante (pour l'instant)
[524]407
[5246]408  !  calcul du nombre de maille sur lequel on advecte plus que la maille.
[524]409
[5246]410  n0=0
411  DO l=1,llm
412     nl(l)=0
413     DO ij=iip2,ip1jm
414        nl(l)=nl(l)+iadvplus(ij,l)
415     ENDDO
416     n0=n0+nl(l)
417  ENDDO
[524]418
[5246]419  IF(n0.gt.0) THEN
420  !cc      PRINT*,'Nombre de points pour lesquels on advect plus que le'
421  !cc     &       ,'contenu de la maille : ',n0
[524]422
[5246]423     DO l=1,llm
424        IF(nl(l).gt.0) THEN
425           iju=0
426  !   indicage des mailles concernees par le traitement special
427           DO ij=iip2,ip1jm
428              IF(iadvplus(ij,l).eq.1.and.mod(ij,iip1).ne.0) THEN
429                 iju=iju+1
430                 indu(iju)=ij
431              ENDIF
432           ENDDO
433           niju=iju
434           ! PRINT*,'niju,nl',niju,nl(l)
[524]435
[5246]436  !  traitement des mailles
437           DO iju=1,niju
438              ij=indu(iju)
439              j=(ij-1)/iip1+1
440              zu_m=u_m(ij,l)
441              u_mq(ij,l)=0.
442              IF(zu_m.gt.0.) THEN
443                 ijq=ij
444                 i=ijq-(j-1)*iip1
445  !   accumulation pour les mailles completements advectees
446                 do while(zu_m.gt.masse(ijq,l,iq))
447                    u_mq(ij,l)=u_mq(ij,l)+q(ijq,l,iq) &
448                          *masse(ijq,l,iq)
449                    zu_m=zu_m-masse(ijq,l,iq)
450                    i=mod(i-2+iim,iim)+1
451                    ijq=(j-1)*iip1+i
452                 ENDDO
453  !   ajout de la maille non completement advectee
454                 u_mq(ij,l)=u_mq(ij,l)+zu_m* &
455                       (q(ijq,l,iq)+0.5*(1.-zu_m/masse(ijq,l,iq)) &
456                       *dxq(ijq,l))
457              ELSE
458                 ijq=ij+1
459                 i=ijq-(j-1)*iip1
460  !   accumulation pour les mailles completements advectees
461                 do while(-zu_m.gt.masse(ijq,l,iq))
462                    u_mq(ij,l)=u_mq(ij,l)-q(ijq,l,iq) &
463                          *masse(ijq,l,iq)
464                    zu_m=zu_m+masse(ijq,l,iq)
465                    i=mod(i,iim)+1
466                    ijq=(j-1)*iip1+i
467                 ENDDO
468  !   ajout de la maille non completement advectee
469                 u_mq(ij,l)=u_mq(ij,l)+zu_m*(q(ijq,l,iq)- &
470                       0.5*(1.+zu_m/masse(ijq,l,iq))*dxq(ijq,l))
471              ENDIF
472           ENDDO
473        ENDIF
474     ENDDO
475  ENDIF  ! n0.gt.0
[524]476
477
478
[5246]479  !   bouclage en latitude
[524]480
[5246]481  DO l=1,llm
482    DO ij=iip1+iip1,ip1jm,iip1
483       u_mq(ij,l)=u_mq(ij-iim,l)
484    ENDDO
485  ENDDO
[524]486
[5246]487  ! CRisi: appel récursif de l'advection sur les fils.
488  ! Il faut faire ça avant d'avoir mis à jour q et masse
489  ! !write(*,*) 'vlspltqs 326: iq,nqChildren(iq)=',iq,
490  ! &                 tracers(iq)%nqChildren
491
492  do ifils=1,tracers(iq)%nqDescen
493    iq2=tracers(iq)%iqDescen(ifils)
494    DO l=1,llm
495      DO ij=iip2,ip1jm
496      ! ! On a besoin de q et masse seulement entre iip2 et ip1jm
497        masseq(ij,l,iq2)=masse(ij,l,iq)*q(ij,l,iq)
498        Ratio(ij,l,iq2)=q(ij,l,iq2)/q(ij,l,iq)
[4050]499      enddo
[5246]500    enddo
501  enddo
502  do ifils=1,tracers(iq)%nqChildren
503    iq2=tracers(iq)%iqDescen(ifils)
504    call vlx(Ratio,pente_max,masseq,u_mq,iq2)
505  enddo
506  ! end CRisi
[524]507
[5246]508  !   calcul des tendances
[524]509
[5246]510  DO l=1,llm
511     DO ij=iip2+1,ip1jm
512        new_m=masse(ij,l,iq)+u_m(ij-1,l)-u_m(ij,l)
513        q(ij,l,iq)=(q(ij,l,iq)*masse(ij,l,iq)+ &
514              u_mq(ij-1,l)-u_mq(ij,l)) &
515              /new_m
516        masse(ij,l,iq)=new_m
517     ENDDO
518  !   Modif Fred 22 03 96 correction d'un bug (les scopy ci-dessous)
519     DO ij=iip1+iip1,ip1jm,iip1
520        q(ij-iim,l,iq)=q(ij,l,iq)
521        masse(ij-iim,l,iq)=masse(ij,l,iq)
522     ENDDO
523  ENDDO
[524]524
[5246]525  ! ! retablir les fils en rapport de melange par rapport a l'air:
526  ! ! On calcule q entre iip2+1,ip1jm -> on fait pareil pour ratio
527  ! ! puis on boucle en longitude
528  do ifils=1,tracers(iq)%nqDescen
529    iq2=tracers(iq)%iqDescen(ifils)
530    DO l=1,llm
531      DO ij=iip2+1,ip1jm
532        q(ij,l,iq2)=q(ij,l,iq)*Ratio(ij,l,iq2)
[4050]533      enddo
[5246]534      DO ij=iip1+iip1,ip1jm,iip1
535        q(ij-iim,l,iq2)=q(ij,l,iq2)
536      enddo
537    enddo
538  enddo
[2270]539
[5246]540  ! CALL SCOPY((jjm-1)*llm,q(iip1+iip1,1),iip1,q(iip2,1),iip1)
541  ! CALL SCOPY((jjm-1)*llm,masse(iip1+iip1,1),iip1,masse(iip2,1),iip1)
[524]542
543
[5246]544  RETURN
545END SUBROUTINE vlxqs
546SUBROUTINE vlyqs(q,pente_max,masse,masse_adv_v,qsat,iq)
547  USE infotrac, ONLY : nqtot,tracers ! CRisi
548  !
549  ! Auteurs:   P.Le Van, F.Hourdin, F.Forget
550  !
551  !    ********************************************************************
552  ! Shema  d'advection " pseudo amont " .
553  !    ********************************************************************
554  ! q,masse_adv_v,w sont des arguments d'entree  pour le s-pg ....
555  !     qsat           est   un argument de sortie pour le s-pg ....
556  !
557  !
558  !   --------------------------------------------------------------------
[524]559
[5246]560  USE comconst_mod, ONLY: pi
[524]561
[5271]562  USE dimensions_mod, ONLY: iim, jjm, llm, ndm
[5272]563USE paramet_mod_h, ONLY: iip1, iip2, iip3, jjp1, llmp1, llmp2, llmm1, kftd, ip1jm, ip1jmp1, &
564          ip1jmi1, ijp1llm, ijmllm, mvar, jcfil, jcfllm
[5271]565IMPLICIT NONE
[5246]566  !
[5271]567
[5272]568
[5246]569  include "comgeom.h"
570  !
571  !
572  !   Arguments:
573  !   ----------
574  REAL :: masse(ip1jmp1,llm,nqtot),pente_max
575  REAL :: masse_adv_v( ip1jm,llm)
576  REAL :: q(ip1jmp1,llm,nqtot)
577  REAL :: qsat(ip1jmp1,llm)
578  INTEGER :: iq ! CRisi
579  !
580  !  Local
581  !   ---------
582  !
583  INTEGER :: i,ij,l
584  !
585  REAL :: airej2,airejjm,airescb(iim),airesch(iim)
586  REAL :: dyq(ip1jmp1,llm),dyqv(ip1jm)
587  REAL :: adyqv(ip1jm),dyqmax(ip1jmp1)
588  REAL :: qbyv(ip1jm,llm)
[2270]589
[5246]590  REAL :: qpns,qpsn,dyn1,dys1,dyn2,dys2,newmasse,fn,fs
591  ! REAL newq,oldmasse
592  Logical :: first,testcpu
593  REAL :: temps0,temps1,temps2,temps3,temps4,temps5
594  SAVE temps0,temps1,temps2,temps3,temps4,temps5
595  SAVE first,testcpu
[524]596
[5246]597  REAL :: convpn,convps,convmpn,convmps
598  REAL :: sinlon(iip1),sinlondlon(iip1)
599  REAL :: coslon(iip1),coslondlon(iip1)
600  SAVE sinlon,coslon,sinlondlon,coslondlon
601  SAVE airej2,airejjm
[524]602
[5246]603  REAL :: masseq(ip1jmp1,llm,nqtot),Ratio(ip1jmp1,llm,nqtot) ! CRisi
604  INTEGER :: ifils,iq2 ! CRisi
605  !
606  !
607  REAL :: SSUM
[524]608
[5246]609  DATA first,testcpu/.true.,.false./
610  DATA temps0,temps1,temps2,temps3,temps4,temps5/0.,0.,0.,0.,0.,0./
[524]611
[5246]612  IF(first) THEN
613     PRINT*,'Shema  Amont nouveau  appele dans  Vanleer   '
614     first=.false.
615     do i=2,iip1
616        coslon(i)=cos(rlonv(i))
617        sinlon(i)=sin(rlonv(i))
618        coslondlon(i)=coslon(i)*(rlonu(i)-rlonu(i-1))/pi
619        sinlondlon(i)=sinlon(i)*(rlonu(i)-rlonu(i-1))/pi
620     ENDDO
621     coslon(1)=coslon(iip1)
622     coslondlon(1)=coslondlon(iip1)
623     sinlon(1)=sinlon(iip1)
624     sinlondlon(1)=sinlondlon(iip1)
625     airej2 = SSUM( iim, aire(iip2), 1 )
626     airejjm= SSUM( iim, aire(ip1jm -iim), 1 )
627  ENDIF
[524]628
[5246]629  !
[524]630
631
[5246]632  DO l = 1, llm
633  !
634  !   --------------------------------
635  !  CALCUL EN LATITUDE
636  !   --------------------------------
[524]637
[5246]638  !   On commence par calculer la valeur du traceur moyenne sur le premier cercle
639  !   de latitude autour du pole (qpns pour le pole nord et qpsn pour
640  !    le pole nord) qui sera utilisee pour evaluer les pentes au pole.
[524]641
[5246]642  DO i = 1, iim
643  airescb(i) = aire(i+ iip1) * q(i+ iip1,l,iq)
644  airesch(i) = aire(i+ ip1jm- iip1) * q(i+ ip1jm- iip1,l,iq)
645  ENDDO
646  qpns   = SSUM( iim,  airescb ,1 ) / airej2
647  qpsn   = SSUM( iim,  airesch ,1 ) / airejjm
[524]648
[5246]649  !   calcul des pentes aux points v
[524]650
[5246]651  DO ij=1,ip1jm
652     dyqv(ij)=q(ij,l,iq)-q(ij+iip1,l,iq)
653     adyqv(ij)=abs(dyqv(ij))
654  ENDDO
[524]655
[5246]656  !   calcul des pentes aux points scalaires
[524]657
[5246]658  DO ij=iip2,ip1jm
659     dyq(ij,l)=.5*(dyqv(ij-iip1)+dyqv(ij))
660     dyqmax(ij)=min(adyqv(ij-iip1),adyqv(ij))
661     dyqmax(ij)=pente_max*dyqmax(ij)
662  ENDDO
[524]663
[5246]664  !   calcul des pentes aux poles
[524]665
[5246]666  DO ij=1,iip1
667     dyq(ij,l)=qpns-q(ij+iip1,l,iq)
668     dyq(ip1jm+ij,l)=q(ip1jm+ij-iip1,l,iq)-qpsn
669  ENDDO
[524]670
[5246]671  !   filtrage de la derivee
672  dyn1=0.
673  dys1=0.
674  dyn2=0.
675  dys2=0.
676  DO ij=1,iim
677     dyn1=dyn1+sinlondlon(ij)*dyq(ij,l)
678     dys1=dys1+sinlondlon(ij)*dyq(ip1jm+ij,l)
679     dyn2=dyn2+coslondlon(ij)*dyq(ij,l)
680     dys2=dys2+coslondlon(ij)*dyq(ip1jm+ij,l)
681  ENDDO
682  DO ij=1,iip1
683     dyq(ij,l)=dyn1*sinlon(ij)+dyn2*coslon(ij)
684     dyq(ip1jm+ij,l)=dys1*sinlon(ij)+dys2*coslon(ij)
685  ENDDO
[524]686
[5246]687  !   calcul des pentes limites aux poles
[524]688
[5246]689  fn=1.
690  fs=1.
691  DO ij=1,iim
692     IF(pente_max*adyqv(ij).lt.abs(dyq(ij,l))) THEN
693        fn=min(pente_max*adyqv(ij)/abs(dyq(ij,l)),fn)
694     ENDIF
695  IF(pente_max*adyqv(ij+ip1jm-iip1).lt.abs(dyq(ij+ip1jm,l))) THEN
696     fs=min(pente_max*adyqv(ij+ip1jm-iip1)/abs(dyq(ij+ip1jm,l)),fs)
697     ENDIF
698  ENDDO
699  DO ij=1,iip1
700     dyq(ij,l)=fn*dyq(ij,l)
701     dyq(ip1jm+ij,l)=fs*dyq(ip1jm+ij,l)
702  ENDDO
[524]703
[5246]704  !CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
705  !  En memoire de dIFferents tests sur la
706  !  limitation des pentes aux poles.
707  !CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
708  ! PRINT*,dyq(1)
709  ! PRINT*,dyqv(iip1+1)
710  ! appn=abs(dyq(1)/dyqv(iip1+1))
711  ! PRINT*,dyq(ip1jm+1)
712  ! PRINT*,dyqv(ip1jm-iip1+1)
713  ! apps=abs(dyq(ip1jm+1)/dyqv(ip1jm-iip1+1))
714  ! DO ij=2,iim
715  !    appn=amax1(abs(dyq(ij)/dyqv(ij)),appn)
716  !    apps=amax1(abs(dyq(ip1jm+ij)/dyqv(ip1jm-iip1+ij)),apps)
717  ! ENDDO
718  ! appn=min(pente_max/appn,1.)
719  ! apps=min(pente_max/apps,1.)
720  !
721  !
722  !   cas ou on a un extremum au pole
723  !
724  ! IF(dyqv(ismin(iim,dyqv,1))*dyqv(ismax(iim,dyqv,1)).le.0.)
725  !    &   appn=0.
726  ! IF(dyqv(ismax(iim,dyqv(ip1jm-iip1+1),1)+ip1jm-iip1+1)*
727  !    &   dyqv(ismin(iim,dyqv(ip1jm-iip1+1),1)+ip1jm-iip1+1).le.0.)
728  !    &   apps=0.
729  !
730  !   limitation des pentes aux poles
731  ! DO ij=1,iip1
732  !    dyq(ij)=appn*dyq(ij)
733  !    dyq(ip1jm+ij)=apps*dyq(ip1jm+ij)
734  ! ENDDO
735  !
736  !   test
737  !  DO ij=1,iip1
738  !     dyq(iip1+ij)=0.
739  !     dyq(ip1jm+ij-iip1)=0.
740  !  ENDDO
741  !  DO ij=1,ip1jmp1
742  !     dyq(ij)=dyq(ij)*cos(rlatu((ij-1)/iip1+1))
743  !  ENDDO
744  !
745  ! changement 10 07 96
746  ! IF(dyqv(ismin(iim,dyqv,1))*dyqv(ismax(iim,dyqv,1)).le.0.)
747  !    &   THEN
748  !    DO ij=1,iip1
749  !       dyqmax(ij)=0.
750  !    ENDDO
751  ! ELSE
752  !    DO ij=1,iip1
753  !       dyqmax(ij)=pente_max*abs(dyqv(ij))
754  !    ENDDO
755  ! ENDIF
756  !
757  ! IF(dyqv(ismax(iim,dyqv(ip1jm-iip1+1),1)+ip1jm-iip1+1)*
758  !    & dyqv(ismin(iim,dyqv(ip1jm-iip1+1),1)+ip1jm-iip1+1).le.0.)
759  !    &THEN
760  !    DO ij=ip1jm+1,ip1jmp1
761  !       dyqmax(ij)=0.
762  !    ENDDO
763  ! ELSE
764  !    DO ij=ip1jm+1,ip1jmp1
765  !       dyqmax(ij)=pente_max*abs(dyqv(ij-iip1))
766  !    ENDDO
767  ! ENDIF
768  !   fin changement 10 07 96
769  !CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
[524]770
[5246]771  !   calcul des pentes limitees
[524]772
[5246]773  DO ij=iip2,ip1jm
774     IF(dyqv(ij)*dyqv(ij-iip1).gt.0.) THEN
775        dyq(ij,l)=sign(min(abs(dyq(ij,l)),dyqmax(ij)),dyq(ij,l))
776     ELSE
777        dyq(ij,l)=0.
778     ENDIF
779  ENDDO
[524]780
[5246]781  ENDDO
[524]782
[5246]783  DO l=1,llm
784   DO ij=1,ip1jm
785     IF( masse_adv_v(ij,l).GT.0. ) THEN
786       qbyv(ij,l)= MIN( qsat(ij+iip1,l), q(ij+iip1,l,iq )  + &
787             dyq(ij+iip1,l)*0.5*(1.-masse_adv_v(ij,l) &
788             /masse(ij+iip1,l,iq)))
789     ELSE
790          qbyv(ij,l)= MIN( qsat(ij,l), q(ij,l,iq) - dyq(ij,l) * &
791                0.5*(1.+masse_adv_v(ij,l)/masse(ij,l,iq)) )
792     ENDIF
793      qbyv(ij,l) = masse_adv_v(ij,l)*qbyv(ij,l)
794   ENDDO
795  ENDDO
796
797
798  ! CRisi: appel récursif de l'advection sur les fils.
799  ! Il faut faire ça avant d'avoir mis à jour q et masse
800  ! !write(*,*) 'vlyqs 689: iq,nqChildren(iq)=',iq,
801  ! &              tracers(iq)%nqChildren
802
803  do ifils=1,tracers(iq)%nqDescen
804    iq2=tracers(iq)%iqDescen(ifils)
805    DO l=1,llm
806      DO ij=1,ip1jmp1
807        masseq(ij,l,iq2)=masse(ij,l,iq)*q(ij,l,iq)
808        Ratio(ij,l,iq2)=q(ij,l,iq2)/q(ij,l,iq)
[4050]809      enddo
[5246]810    enddo
811  enddo
812  do ifils=1,tracers(iq)%nqChildren
813    iq2=tracers(iq)%iqDescen(ifils)
814    ! !write(*,*) 'vlyqs 783: appel rec de vly, iq2=',iq2
815    call vly(Ratio,pente_max,masseq,qbyv,iq2)
816  enddo
[2270]817
[5246]818  DO l=1,llm
819     DO ij=iip2,ip1jm
820        newmasse=masse(ij,l,iq) &
821              +masse_adv_v(ij,l)-masse_adv_v(ij-iip1,l)
822        q(ij,l,iq)=(q(ij,l,iq)*masse(ij,l,iq)+qbyv(ij,l) &
823              -qbyv(ij-iip1,l))/newmasse
824        masse(ij,l,iq)=newmasse
825     ENDDO
826  !.-. ancienne version
827     convpn=SSUM(iim,qbyv(1,l),1)/apoln
828     convmpn=ssum(iim,masse_adv_v(1,l),1)/apoln
829     DO ij = 1,iip1
830        newmasse=masse(ij,l,iq)+convmpn*aire(ij)
831        q(ij,l,iq)=(q(ij,l,iq)*masse(ij,l,iq)+convpn*aire(ij))/ &
832              newmasse
833        masse(ij,l,iq)=newmasse
834     ENDDO
835     convps  = -SSUM(iim,qbyv(ip1jm-iim,l),1)/apols
836     convmps = -SSUM(iim,masse_adv_v(ip1jm-iim,l),1)/apols
837     DO ij = ip1jm+1,ip1jmp1
838        newmasse=masse(ij,l,iq)+convmps*aire(ij)
839        q(ij,l,iq)=(q(ij,l,iq)*masse(ij,l,iq)+convps*aire(ij))/ &
840              newmasse
841        masse(ij,l,iq)=newmasse
842     ENDDO
843  !.-. fin ancienne version
[524]844
[5246]845  !._. nouvelle version
846     ! convpn=SSUM(iim,qbyv(1,l),1)
847     ! convmpn=ssum(iim,masse_adv_v(1,l),1)
848     ! oldmasse=ssum(iim,masse(1,l),1)
849     ! newmasse=oldmasse+convmpn
850     ! newq=(q(1,l)*oldmasse+convpn)/newmasse
851     ! newmasse=newmasse/apoln
852     ! DO ij = 1,iip1
853     !    q(ij,l)=newq
854     !    masse(ij,l,iq)=newmasse*aire(ij)
855     ! ENDDO
856     ! convps=-SSUM(iim,qbyv(ip1jm-iim,l),1)
857     ! convmps=-ssum(iim,masse_adv_v(ip1jm-iim,l),1)
858     ! oldmasse=ssum(iim,masse(ip1jm-iim,l),1)
859     ! newmasse=oldmasse+convmps
860     ! newq=(q(ip1jmp1,l)*oldmasse+convps)/newmasse
861     ! newmasse=newmasse/apols
862     ! DO ij = ip1jm+1,ip1jmp1
863     !    q(ij,l)=newq
864     !    masse(ij,l,iq)=newmasse*aire(ij)
865     ! ENDDO
866  !._. fin nouvelle version
867  ENDDO
[524]868
[5246]869  ! !write(*,*) 'vly 866'
[2270]870
[5246]871  ! retablir les fils en rapport de melange par rapport a l'air:
872  do ifils=1,tracers(iq)%nqDescen
873    iq2=tracers(iq)%iqDescen(ifils)
874    DO l=1,llm
875      DO ij=1,ip1jmp1
876        q(ij,l,iq2)=q(ij,l,iq)*Ratio(ij,l,iq2)
[4050]877      enddo
[5246]878    enddo
879  enddo
880  ! !write(*,*) 'vly 879'
[2270]881
[5246]882  RETURN
883END SUBROUTINE vlyqs
Note: See TracBrowser for help on using the repository browser.