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

Last change on this file since 5273 was 5272, checked in by abarral, 2 days 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
Line 
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  !   --------------------------------------------------------------------
25
26  USE comconst_mod, ONLY: cpp
27  USE logic_mod, ONLY: adv_qsat_liq
28  USE dimensions_mod, ONLY: iim, jjm, llm, ndm
29USE paramet_mod_h, ONLY: iip1, iip2, iip3, jjp1, llmp1, llmp2, llmm1, kftd, ip1jm, ip1jmp1, &
30          ip1jmi1, ijp1llm, ijmllm, mvar, jcfil, jcfllm
31IMPLICIT NONE
32  !
33
34
35
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
63
64  REAL :: qmin,qmax
65  DATA qmin,qmax/0.,1.e33/
66  DATA testcpu/.false./
67  DATA temps1,temps2,temps3/0.,0.,0./
68
69  !--pour rapport de melange saturant--
70
71  REAL :: rtt,retv,r2es,r3les,r3ies,r4les,r4ies,play
72  REAL :: ptarg,pdelarg,foeew,zdelta
73  REAL :: tempe(ip1jmp1)
74
75  !    fonction psat(T)
76
77   FOEEW ( PTARG,PDELARG ) = EXP ( &
78         (R3LES*(1.-PDELARG)+R3IES*PDELARG) * (PTARG-RTT) &
79         / (PTARG-(R4LES*(1.-PDELARG)+R4IES*PDELARG)) )
80
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
88
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
107
108   ! PRINT*,'Debut vlsplt version debug sans vlyqs'
109
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
123
124  DO ij=1,ip1jmp1
125     mw(ij,llm+1)=0.
126  ENDDO
127
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
134
135   ! call minmaxq(zq,qmin,qmax,'avant vlxqs     ')
136  call vlxqs(zq,pente_max,zm,mu,qsat,iq)
137
138  ! call minmaxq(zq,qmin,qmax,'avant vlyqs     ')
139
140  call vlyqs(zq,pente_max,zm,mv,qsat,iq)
141
142   ! call minmaxq(zq,qmin,qmax,'avant vlz     ')
143
144  call vlz(zq,pente_max,zm,mw,iq)
145
146  ! call minmaxq(zq,qmin,qmax,'avant vlyqs     ')
147  ! call minmaxq(zm,qmin,qmax,'M avant vlyqs     ')
148
149  call vlyqs(zq,pente_max,zm,mv,qsat,iq)
150
151  ! call minmaxq(zq,qmin,qmax,'avant vlxqs     ')
152  ! call minmaxq(zm,qmin,qmax,'M avant vlxqs     ')
153
154  call vlxqs(zq,pente_max,zm,mu,qsat,iq)
155
156  ! call minmaxq(zq,qmin,qmax,'apres vlxqs     ')
157  ! call minmaxq(zm,qmin,qmax,'M apres vlxqs     ')
158
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)
174      ENDDO
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'
181
182  RETURN
183END SUBROUTINE vlspltqs
184SUBROUTINE vlxqs(q,pente_max,masse,u_m,qsat,iq)
185  USE infotrac, ONLY : nqtot,tracers ! CRisi
186
187  !
188  ! Auteurs:   P.Le Van, F.Hourdin, F.Forget
189  !
190  !    ********************************************************************
191  ! Shema  d'advection " pseudo amont " .
192  !    ********************************************************************
193  !
194  !   --------------------------------------------------------------------
195  USE dimensions_mod, ONLY: iim, jjm, llm, ndm
196USE paramet_mod_h, ONLY: iip1, iip2, iip3, jjp1, llmp1, llmp2, llmm1, kftd, ip1jm, ip1jmp1, &
197          ip1jmi1, ijp1llm, ijmllm, mvar, jcfil, jcfllm
198IMPLICIT NONE
199  !
200
201
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)
223
224  ! ! CRisi
225  REAL :: masseq(ip1jmp1,llm,nqtot),Ratio(ip1jmp1,llm,nqtot)
226  INTEGER :: ifils,iq2 ! CRisi
227
228  Logical :: first,testcpu
229  SAVE first,testcpu
230
231  REAL :: SSUM
232  REAL :: temps0,temps1,temps2,temps3,temps4,temps5
233  SAVE temps0,temps1,temps2,temps3,temps4,temps5
234
235
236  DATA first,testcpu/.true.,.false./
237
238  IF(first) THEN
239     temps1=0.
240     temps2=0.
241     temps3=0.
242     temps4=0.
243     temps5=0.
244     first=.false.
245  ENDIF
246
247  !   calcul de la pente a droite et a gauche de la maille
248
249
250  IF (pente_max.gt.-1.e-5) THEN
251  ! IF (pente_max.gt.10) THEN
252
253  !   calcul des pentes avec limitation, Van Leer scheme I:
254  !   -----------------------------------------------------
255
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
265
266        DO ij=iip2,ip1jm
267           adxqu(ij)=abs(dxqu(ij))
268        ENDDO
269
270  !   calcul de la pente maximum dans la maille en valeur absolue
271
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)))
277
278
279        ENDDO
280
281        DO ij=iip1+iip1,ip1jm,iip1
282           dxqmax(ij-iim,l)=dxqmax(ij,l)
283        ENDDO
284
285        DO ij=iip2+1,ip1jm
286#ifdef CRAY
287           dxq(ij,l)= &
288                 cvmgp(dxqu(ij-1)+dxqu(ij),0.,dxqu(ij-1)*dxqu(ij))
289#else
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
296#endif
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
301
302     ENDDO ! l=1,llm
303
304  ELSE ! (pente_max.lt.-1.e-5)
305
306  !   Pentes produits:
307  !   ----------------
308
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
316
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
327
328     ENDDO
329
330  ENDIF ! (pente_max.lt.-1.e-5)
331
332  !   bouclage de la pente en iip1:
333  !   -----------------------------
334
335  DO l=1,llm
336     DO ij=iip1+iip1,ip1jm,iip1
337        dxq(ij-iim,l)=dxq(ij,l)
338     ENDDO
339
340     DO ij=1,ip1jmp1
341        iadvplus(ij,l)=0
342     ENDDO
343
344  ENDDO
345
346
347  !   calcul des flux a gauche et a droite
348
349#ifdef CRAY
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
364#else
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
381#endif
382
383
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
399
400
401
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.
405
406  !   pas d'influence de la pression saturante (pour l'instant)
407
408  !  calcul du nombre de maille sur lequel on advecte plus que la maille.
409
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
418
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
422
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)
435
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
476
477
478
479  !   bouclage en latitude
480
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
486
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)
499      enddo
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
507
508  !   calcul des tendances
509
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
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)
533      enddo
534      DO ij=iip1+iip1,ip1jm,iip1
535        q(ij-iim,l,iq2)=q(ij,l,iq2)
536      enddo
537    enddo
538  enddo
539
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)
542
543
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  !   --------------------------------------------------------------------
559
560  USE comconst_mod, ONLY: pi
561
562  USE dimensions_mod, ONLY: iim, jjm, llm, ndm
563USE paramet_mod_h, ONLY: iip1, iip2, iip3, jjp1, llmp1, llmp2, llmm1, kftd, ip1jm, ip1jmp1, &
564          ip1jmi1, ijp1llm, ijmllm, mvar, jcfil, jcfllm
565IMPLICIT NONE
566  !
567
568
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)
589
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
596
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
602
603  REAL :: masseq(ip1jmp1,llm,nqtot),Ratio(ip1jmp1,llm,nqtot) ! CRisi
604  INTEGER :: ifils,iq2 ! CRisi
605  !
606  !
607  REAL :: SSUM
608
609  DATA first,testcpu/.true.,.false./
610  DATA temps0,temps1,temps2,temps3,temps4,temps5/0.,0.,0.,0.,0.,0./
611
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
628
629  !
630
631
632  DO l = 1, llm
633  !
634  !   --------------------------------
635  !  CALCUL EN LATITUDE
636  !   --------------------------------
637
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.
641
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
648
649  !   calcul des pentes aux points v
650
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
655
656  !   calcul des pentes aux points scalaires
657
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
663
664  !   calcul des pentes aux poles
665
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
670
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
686
687  !   calcul des pentes limites aux poles
688
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
703
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
770
771  !   calcul des pentes limitees
772
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
780
781  ENDDO
782
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)
809      enddo
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
817
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
844
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
868
869  ! !write(*,*) 'vly 866'
870
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)
877      enddo
878    enddo
879  enddo
880  ! !write(*,*) 'vly 879'
881
882  RETURN
883END SUBROUTINE vlyqs
Note: See TracBrowser for help on using the repository browser.