source: LMDZ6/branches/LMDZ-tracers/libf/dyn3dmem/vlspltqs_loc.F @ 3961

Last change on this file since 3961 was 3957, checked in by dcugnet, 3 years ago

In readTracFiles: the separator between the tracer name and its phase is no longer hardcoded and equal to "-",
but is a parameter ("phases_sep") which default value is "_".
Few more fixes.

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