source: LMDZ.3.3/branches/rel-LF/libf/dyn3d/vlsplt.F @ 4122

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

Si il n'y avait qu'un point ou on advectait plus que le contenu de la maille,
il n'etait jamais traite. YM
LF

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