source: LMDZ4/trunk/libf/dyn3dpar/vlsplt.F @ 663

Last change on this file since 663 was 630, checked in by Laurent Fairhead, 20 years ago

Import d'une version parallele de la dynamique YM
LF

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