source: LMDZ5/trunk/libf/dyn3d/vlspltqs.F @ 2601

Last change on this file since 2601 was 2600, checked in by Ehouarn Millour, 9 years ago

Cleanup in the dynamics: turn comvert.h into module comvert_mod.F90
EM

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