source: LMDZ.3.3/trunk/libf/dyn3d/vlsplt.F @ 5306

Last change on this file since 5306 was 357, checked in by lmdz, 23 years ago

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