source: codes/icosagcm/branches/SATURN_DYNAMICO/LMDZ.COMMON/libf/dyn3dpar/vlspltqs_p.F @ 222

Last change on this file since 222 was 222, checked in by ymipsl, 10 years ago

Creating temporary dynamico/lmdz/saturn branche

YM

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