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

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

Import d'une version parallele de la dynamique YM
LF

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