source: LMDZ5/trunk/libf/dyn3dpar/vlspltqs_p.F @ 2600

Last change on this file since 2600 was 2600, checked in by Ehouarn Millour, 8 years ago

Cleanup in the dynamics: turn comvert.h into module comvert_mod.F90
EM

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