source: LMDZ5/trunk/libf/dyn3dmem/vlspltqs_loc.F @ 2602

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