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

Last change on this file since 1243 was 135, checked in by aslmd, 14 years ago

CHANGEMENT ARBORESCENCE ETAPE 2 -- NON COMPLET

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