source: trunk/LMDZ.COMMON/libf/dyn3d/vlsplt.F @ 1428

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