source: trunk/LMDZ.COMMON/libf/dyn3dpar/vlspltqs_p.F @ 3567

Last change on this file since 3567 was 1422, checked in by milmd, 10 years ago

In GENERIC, MARS and COMMON models replace some include files by modules (usefull for decoupling physics with dynamics).

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