source: trunk/LMDZ.GENERIC/libf/dyn3d/vlsplt.F @ 1422

Last change on this file since 1422 was 1422, checked in by milmd, 10 years ago

In GENERIC, MARS and COMMON models replace some include files by modules (usefull for decoupling physics with dynamics).

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