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

Last change on this file since 3852 was 3852, checked in by dcugnet, 4 years ago

Extension of the tracers management.

The tracers files can be:

1) "traceur.def": old format, with:

  • the number of tracers on the first line
  • one line for each tracer: <tracer name> <hadv> <vadv> [<parent name>]

2) "tracer.def": new format with one section each model component.
3) "tracer_<name>.def": new format with a single section.

The formats 2 and 3 reading is driven by the "type_trac" key, which can be a

coma-separated list of components.

  • Format 2: read the sections from the "tracer.def" file.
  • format 3: read one section each "tracer_<section name>.def" file.
  • the first line of a section is "&<section name>
  • the other lines start with a tracer name followed by <key>=<val> pairs.
  • the "default" tracer name is reserved ; the other tracers of the section inherit its <key>=<val>, except for the keys that are redefined locally.

This format helps keeping the tracers files compact, thanks to the "default"
special tracer and the three levels of factorization:

  • on the tracers names: a tracer name can be a coma-separated list of tracers => all the tracers of the list have the same <key>=<val> properties
  • on the parents names: the value of the "parent" property can be a coma-separated list of tracers => only possible for geographic tagging tracers
  • on the phases: the property "phases" is [g](l][s] (gas/liquid/solid)

Read information is stored in the vector "tracers(:)", of derived type "tra".

"isotopes_params.def" is a similar file, with one section each isotopes family.
It contains a database of isotopes properties ; if there are second generation
tracers (isotopes), the corresponding sections are read.

Read information is stored in the vector "isotopes(:)", of derived type "iso".

The "getKey" function helps to get the values of the parameters stored in
"tracers" or "isotopes".

  • 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
RevLine 
[3851]1!
2!     $Id: vlspltqs_loc.F 3852 2021-02-22 16:28:31Z dcugnet $
3!
[2270]4      SUBROUTINE vlxqs_loc(q,pente_max,masse,u_m,qsat,ijb_x,ije_x,iq)
[1632]5c
6c     Auteurs:   P.Le Van, F.Hourdin, F.Forget
7c
8c    ********************************************************************
[2270]9c     Shema  d''advection " pseudo amont " .
[1632]10c    ********************************************************************
11c
12c   --------------------------------------------------------------------
[1823]13      USE parallel_lmdz
[3852]14      USE infotrac, ONLY : nqtot, tracers, tra,        ! CRisi                 &
[3851]15     &                     qperemin,masseqmin,ratiomin ! MVals et CRisi
[1632]16      IMPLICIT NONE
17c
[2597]18      include "dimensions.h"
19      include "paramet.h"
[1632]20c
21c
22c   Arguments:
23c   ----------
[2270]24      REAL masse(ijb_u:ije_u,llm,nqtot),pente_max
[1632]25      REAL u_m( ijb_u:ije_u,llm )
[2270]26      REAL q(ijb_u:ije_u,llm,nqtot)
[1632]27      REAL qsat(ijb_u:ije_u,llm)
[2270]28      INTEGER iq ! CRisi
[1632]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)
[2281]41      REAL Ratio(ijb_u:ije_u,llm,nqtot) ! CRisi
[3852]42      INTEGER ichld,iq2 ! CRisi
43      TYPE(tra), POINTER :: tr
[1632]44
45      REAL      SSUM
46
47
48      INTEGER ijb,ije,ijb_x,ije_x
[3852]49
50      tr => tracers(iq)
51
[2286]52      !write(*,*) 'vlspltqs 58: entree vlxqs_loc, iq,ijb_x=',
53!     &   iq,ijb_x
[1632]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
[2270]77               dxqu(ij)=q(ij+1,l,iq)-q(ij,l,iq)
[1632]78c              IF(u_m(ij,l).lt.0.) stop'limx n admet pas les U<0'
[2270]79c              sigu(ij)=u_m(ij,l)/masse(ij,l,iq)
[1632]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
[2270]132               dxqu(ij)=q(ij+1,l,iq)-q(ij,l,iq)
[1632]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
[2600]179          iadvplus(ip1jm+1:ip1jmp1,l)=0
[1632]180        ENDDO
181c$OMP END DO NOWAIT
182      endif
[2600]183             
[1632]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
[2270]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),
[1632]193     ,                     u_m(ij,l))
194          zdum(ij,l)=0.5*zdum(ij,l)
195          u_mq(ij,l)=cvmgp(
[2270]196     ,                q(ij,l,iq)+zdum(ij,l)*dxq(ij,l),
197     ,                q(ij+1,l,iq)-zdum(ij,l)*dxq(ij+1,l),
[1632]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.
[2270]207c   le rapport de melange de l''air advecte est min(q_vanleer, Qsat_downwind)
[1632]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
[2270]212             zdum(ij,l)=1.-u_m(ij,l)/masse(ij,l,iq)
[1632]213             u_mq(ij,l)=u_m(ij,l)*
[2270]214     $         min(q(ij,l,iq)+0.5*zdum(ij,l)*dxq(ij,l),qsat(ij+1,l))
[1632]215          ELSE
[2270]216             zdum(ij,l)=1.+u_m(ij,l)/masse(ij+1,l,iq)
[1632]217             u_mq(ij,l)=u_m(ij,l)*
[2270]218     $         min(q(ij+1,l,iq)-0.5*zdum(ij,l)*dxq(ij+1,l),qsat(ij,l))
[1632]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
[2286]285               !PRINT*,'vlxqs 280: niju,nl',niju,nl(l)
[1632]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
[2270]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)
[1632]301                        i=mod(i-2+iim,iim)+1
302                        ijq=(j-1)*iip1+i
303                     ENDDO
304c   ajout de la maille non completement advectee
[2270]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))
[1632]307                  ELSE
308                     ijq=ij+1
309                     i=ijq-(j-1)*iip1
310c   accumulation pour les mailles completements advectees
[2270]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)
[1632]315                        i=mod(i,iim)+1
316                        ijq=(j-1)*iip1+i
317                     ENDDO
318c   ajout de la maille non completement advectee
[2270]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))
[1632]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
[2270]339! CRisi: appel récursif de l'advection sur les fils.
340! Il faut faire ça avant d'avoir mis à jour q et masse
[3852]341      !write(*,*) 'vlspltqs 336: iq,ijb_x,tr%nchld=',
342!     &     iq,ijb_x,tr%nchld 
[2270]343
[3852]344      if(tr%ndesc > 0) then 
345       do ichld=1,tr%ndesc
346         iq2=tr%idesc(ichld)
[2270]347c$OMP DO SCHEDULE(STATIC,OMP_CHUNK)   
348         DO l=1,llm
349          DO ij=ijb,ije
[3851]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),masseqmin)
352           if (q(ij,l,iq).gt.qperemin) 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
[2270]357          enddo   
358         enddo
359c$OMP END DO NOWAIT
[3852]360        enddo !do ichld=1,tr%nchld
361        do ichld=1,tr%nchld
362         iq2=tr%idesc(ichld)
[2286]363         !write(*,*) 'vlxqs 349: on appelle vlx pour iq2=',iq2
[2281]364         call vlx_loc(Ratio,pente_max,masse,u_mq,ijb_x,ije_x,iq2)
[3852]365        enddo !do ichld=1,tr%nchld
366      endif !if(tr%ndesc > 0)
[2270]367! end CRisi
368
[2286]369      !write(*,*) 'vlspltqs 360: iq,ijb_x=',iq,ijb_x   
[2270]370
[1632]371c   calcul des tendances
372c$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
373      DO l=1,llm
374         DO ij=ijb+1,ije
[3851]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),masseqmin)
[2270]377            q(ij,l,iq)=(q(ij,l,iq)*masse(ij,l,iq)+
[1632]378     &      u_mq(ij-1,l)-u_mq(ij,l))
379     &      /new_m
[2270]380            masse(ij,l,iq)=new_m
[1632]381         ENDDO
[2270]382c   Modif Fred 22 03 96 correction d''un bug (les scopy ci-dessous)
[1632]383         DO ij=ijb+iip1-1,ije,iip1
[2270]384            q(ij-iim,l,iq)=q(ij,l,iq)
385            masse(ij-iim,l,iq)=masse(ij,l,iq)
[1632]386         ENDDO
387      ENDDO
388c$OMP END DO NOWAIT
[2270]389
[2286]390      !write(*,*) 'vlspltqs 380: iq,ijb_x=',iq,ijb_x
[2270]391
392! retablir les fils en rapport de melange par rapport a l'air:
[3852]393      if(tr%ndesc > 0) then 
394       do ichld=1,tr%ndesc
395         iq2=tr%idesc(ichld) 
[2270]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
[3852]406        enddo !do ichld=1,tr%ndesc
407      endif !if(tr%ndesc > 0)
[2270]408
[2286]409      !write(*,*) 'vlspltqs 399: iq,ijb_x=',iq,ijb_x
[2270]410
[1632]411c     CALL SCOPY((jjm-1)*llm,q(iip1+iip1,1),iip1,q(iip2,1),iip1)
[2270]412c     CALL SCOPY((jjm-1)*llm,masse(iip1+iip1,1,iq),iip1,masse(iip2,1,iq),iip1)
[1632]413
414
415      RETURN
416      END
[2270]417      SUBROUTINE vlyqs_loc(q,pente_max,masse,masse_adv_v,qsat,iq)
[1632]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 ....
[2600]425c     qsat                est   un argument de sortie pour le s-pg ....
[1632]426c
427c
428c   --------------------------------------------------------------------
[1823]429      USE parallel_lmdz
[3852]430      USE infotrac, ONLY : nqtot, tracers, tra,        ! CRisi                 &
[3851]431     &                     qperemin,masseqmin,ratiomin ! MVals et CRisi
[2597]432      USE comconst_mod, ONLY: pi
[1632]433      IMPLICIT NONE
434c
[2597]435      include "dimensions.h"
436      include "paramet.h"
437      include "comgeom.h"
[3851]438      include "iniprint.h" 
[1632]439c
440c
441c   Arguments:
442c   ----------
[2270]443      REAL masse(ijb_u:ije_u,llm,nqtot),pente_max
[1632]444      REAL masse_adv_v( ijb_v:ije_v,llm)
[2270]445      REAL q(ijb_u:ije_u,llm,nqtot)
[1632]446      REAL qsat(ijb_u:ije_u,llm)
[2270]447      INTEGER iq ! CRisi
[1632]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)
[2270]457      REAL qbyv(ijb_v:ije_v,llm,nqtot)
[1632]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
[2281]473      REAL Ratio(ijb_u:ije_u,llm,nqtot) ! CRisi
[3852]474      INTEGER ichld,iq2 ! CRisi
475      TYPE(tra), POINTER :: tr
[2270]476
[1632]477      REAL      SSUM
478
479      DATA first/.true./
480      INTEGER ijb,ije
[3851]481      INTEGER ijbm,ijem
[1632]482
[2270]483      ijb=ij_begin-2*iip1
484      ije=ij_end+2*iip1 
485      if (pole_nord) ijb=ij_begin
486      if (pole_sud)  ije=ij_end
487      ij=3525
488      l=3
489      if ((ij.ge.ijb).and.(ij.le.ije)) then
[2286]490        !write(*,*) 'vlyqs 480: ij,l,iq,ijb,q(ij,l,:)=',
491!     &             ij,l,iq,ijb,q(ij,l,:)
[2270]492      endif 
493
[1632]494      IF(first) THEN
495         PRINT*,'Shema  Amont nouveau  appele dans  Vanleer   '
[2270]496         PRINT*,'vlyqs_loc, iq=',iq
[1632]497         first=.false.
498         do i=2,iip1
499            coslon(i)=cos(rlonv(i))
500            sinlon(i)=sin(rlonv(i))
501            coslondlon(i)=coslon(i)*(rlonu(i)-rlonu(i-1))/pi
502            sinlondlon(i)=sinlon(i)*(rlonu(i)-rlonu(i-1))/pi
503         ENDDO
504         coslon(1)=coslon(iip1)
505         coslondlon(1)=coslondlon(iip1)
506         sinlon(1)=sinlon(iip1)
507         sinlondlon(1)=sinlondlon(iip1)
508         airej2 = SSUM( iim, aire(iip2), 1 )
509         airejjm= SSUM( iim, aire(ip1jm -iim), 1 )
510      ENDIF
511
512c
513
514c$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
515      DO l = 1, llm
516c
517c   --------------------------------
518c      CALCUL EN LATITUDE
519c   --------------------------------
520
521c   On commence par calculer la valeur du traceur moyenne sur le premier cercle
522c   de latitude autour du pole (qpns pour le pole nord et qpsn pour
523c    le pole nord) qui sera utilisee pour evaluer les pentes au pole.
524
525      if (pole_nord) then
526        DO i = 1, iim
[2270]527          airescb(i) = aire(i+ iip1) * q(i+ iip1,l,iq)
[1632]528        ENDDO
529        qpns   = SSUM( iim,  airescb ,1 ) / airej2
530      endif
531     
532      if (pole_sud) then
533        DO i = 1, iim
[2270]534          airesch(i) = aire(i+ ip1jm- iip1) * q(i+ ip1jm- iip1,l,iq)
[1632]535        ENDDO
536        qpsn   = SSUM( iim,  airesch ,1 ) / airejjm
537      endif
538
539
540c   calcul des pentes aux points v
541
542      ijb=ij_begin-2*iip1
543      ije=ij_end+iip1
544      if (pole_nord) ijb=ij_begin
545      if (pole_sud)  ije=ij_end-iip1
546     
547      DO ij=ijb,ije
[2270]548         dyqv(ij)=q(ij,l,iq)-q(ij+iip1,l,iq)
[1632]549         adyqv(ij)=abs(dyqv(ij))
550      ENDDO
551
552
553c   calcul des pentes aux points scalaires
554
555      ijb=ij_begin-iip1
556      ije=ij_end+iip1
557      if (pole_nord) ijb=ij_begin+iip1
558      if (pole_sud)  ije=ij_end-iip1
559     
560      DO ij=ijb,ije
561         dyq(ij,l)=.5*(dyqv(ij-iip1)+dyqv(ij))
562         dyqmax(ij)=min(adyqv(ij-iip1),adyqv(ij))
563         dyqmax(ij)=pente_max*dyqmax(ij)
564      ENDDO
565     
566      IF (pole_nord) THEN
567
568c   calcul des pentes aux poles
569        DO ij=1,iip1
[2270]570           dyq(ij,l)=qpns-q(ij+iip1,l,iq)
[1632]571        ENDDO
572
573c   filtrage de la derivee       
574        dyn1=0.
575        dyn2=0.
576        DO ij=1,iim
577          dyn1=dyn1+sinlondlon(ij)*dyq(ij,l)
578          dyn2=dyn2+coslondlon(ij)*dyq(ij,l)
579        ENDDO
580        DO ij=1,iip1
581          dyq(ij,l)=dyn1*sinlon(ij)+dyn2*coslon(ij)
582        ENDDO
583
584c   calcul des pentes limites aux poles
585        fn=1.
586        DO ij=1,iim
587          IF(pente_max*adyqv(ij).lt.abs(dyq(ij,l))) THEN
588            fn=min(pente_max*adyqv(ij)/abs(dyq(ij,l)),fn)
589          ENDIF
590        ENDDO
591     
592        DO ij=1,iip1
593         dyq(ij,l)=fn*dyq(ij,l)
594        ENDDO
[2600]595         
[1632]596      ENDIF
597     
598      IF (pole_sud) THEN
599
600        DO ij=1,iip1
[2270]601           dyq(ip1jm+ij,l)=q(ip1jm+ij-iip1,l,iq)-qpsn
[1632]602        ENDDO
603
604        dys1=0.
605        dys2=0.
606
607        DO ij=1,iim
608          dys1=dys1+sinlondlon(ij)*dyq(ip1jm+ij,l)
609          dys2=dys2+coslondlon(ij)*dyq(ip1jm+ij,l)
610        ENDDO
611
612        DO ij=1,iip1
613          dyq(ip1jm+ij,l)=dys1*sinlon(ij)+dys2*coslon(ij)
614        ENDDO
615       
[2600]616c   calcul des pentes limites aux poles       
[1632]617        fs=1.
618        DO ij=1,iim
619        IF(pente_max*adyqv(ij+ip1jm-iip1).lt.abs(dyq(ij+ip1jm,l))) THEN
620         fs=min(pente_max*adyqv(ij+ip1jm-iip1)/abs(dyq(ij+ip1jm,l)),fs)
621        ENDIF
622        ENDDO
623   
624        DO ij=1,iip1
625         dyq(ip1jm+ij,l)=fs*dyq(ip1jm+ij,l)
626        ENDDO
[2600]627       
[1632]628      ENDIF
629
630
631CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
632C  En memoire de dIFferents tests sur la
633C  limitation des pentes aux poles.
634CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
635C     PRINT*,dyq(1)
636C     PRINT*,dyqv(iip1+1)
[1673]637C     appn=abs(dyq(1)/dyqv(iip1+1))
[1632]638C     PRINT*,dyq(ip1jm+1)
639C     PRINT*,dyqv(ip1jm-iip1+1)
[1673]640C     apps=abs(dyq(ip1jm+1)/dyqv(ip1jm-iip1+1))
[1632]641C     DO ij=2,iim
[1673]642C        appn=amax1(abs(dyq(ij)/dyqv(ij)),appn)
643C        apps=amax1(abs(dyq(ip1jm+ij)/dyqv(ip1jm-iip1+ij)),apps)
[1632]644C     ENDDO
[1673]645C     appn=min(pente_max/appn,1.)
646C     apps=min(pente_max/apps,1.)
[1632]647C
648C
649C   cas ou on a un extremum au pole
650C
651C     IF(dyqv(ismin(iim,dyqv,1))*dyqv(ismax(iim,dyqv,1)).le.0.)
[1673]652C    &   appn=0.
[1632]653C     IF(dyqv(ismax(iim,dyqv(ip1jm-iip1+1),1)+ip1jm-iip1+1)*
654C    &   dyqv(ismin(iim,dyqv(ip1jm-iip1+1),1)+ip1jm-iip1+1).le.0.)
[1673]655C    &   apps=0.
[1632]656C
657C   limitation des pentes aux poles
658C     DO ij=1,iip1
[1673]659C        dyq(ij)=appn*dyq(ij)
660C        dyq(ip1jm+ij)=apps*dyq(ip1jm+ij)
[1632]661C     ENDDO
662C
663C   test
664C      DO ij=1,iip1
665C         dyq(iip1+ij)=0.
666C         dyq(ip1jm+ij-iip1)=0.
667C      ENDDO
668C      DO ij=1,ip1jmp1
669C         dyq(ij)=dyq(ij)*cos(rlatu((ij-1)/iip1+1))
670C      ENDDO
671C
672C changement 10 07 96
673C     IF(dyqv(ismin(iim,dyqv,1))*dyqv(ismax(iim,dyqv,1)).le.0.)
674C    &   THEN
675C        DO ij=1,iip1
676C           dyqmax(ij)=0.
677C        ENDDO
678C     ELSE
679C        DO ij=1,iip1
680C           dyqmax(ij)=pente_max*abs(dyqv(ij))
681C        ENDDO
682C     ENDIF
683C
684C     IF(dyqv(ismax(iim,dyqv(ip1jm-iip1+1),1)+ip1jm-iip1+1)*
685C    & dyqv(ismin(iim,dyqv(ip1jm-iip1+1),1)+ip1jm-iip1+1).le.0.)
686C    &THEN
687C        DO ij=ip1jm+1,ip1jmp1
688C           dyqmax(ij)=0.
689C        ENDDO
690C     ELSE
691C        DO ij=ip1jm+1,ip1jmp1
692C           dyqmax(ij)=pente_max*abs(dyqv(ij-iip1))
693C        ENDDO
694C     ENDIF
695C   fin changement 10 07 96
696CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
697
698c   calcul des pentes limitees
699      ijb=ij_begin-iip1
700      ije=ij_end+iip1
701      if (pole_nord) ijb=ij_begin+iip1
702      if (pole_sud)  ije=ij_end-iip1
703
704      DO ij=ijb,ije
705         IF(dyqv(ij)*dyqv(ij-iip1).gt.0.) THEN
706            dyq(ij,l)=sign(min(abs(dyq(ij,l)),dyqmax(ij)),dyq(ij,l))
707         ELSE
708            dyq(ij,l)=0.
709         ENDIF
710      ENDDO
711
712      ENDDO
713c$OMP END DO NOWAIT
714
715      ijb=ij_begin-iip1
716      ije=ij_end
717      if (pole_nord) ijb=ij_begin
718      if (pole_sud)  ije=ij_end-iip1
719
720c$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
721      DO l=1,llm
722       DO ij=ijb,ije
723         IF( masse_adv_v(ij,l).GT.0. ) THEN
[2270]724           qbyv(ij,l,iq)= MIN( qsat(ij+iip1,l), q(ij+iip1,l,iq )  +
725     ,      dyq(ij+iip1,l)*0.5*(1.-masse_adv_v(ij,l)
726     ,      /masse(ij+iip1,l,iq)))
[1632]727         ELSE
[2270]728              qbyv(ij,l,iq)= MIN( qsat(ij,l), q(ij,l,iq) - dyq(ij,l) *
729     ,                   0.5*(1.+masse_adv_v(ij,l)/masse(ij,l,iq)) )
[1632]730         ENDIF
[2270]731          qbyv(ij,l,iq) = masse_adv_v(ij,l)*qbyv(ij,l,iq)
[1632]732       ENDDO
733      ENDDO
734c$OMP END DO NOWAIT
735
[2270]736! CRisi: appel récursif de l'advection sur les fils.
737! Il faut faire ça avant d'avoir mis à jour q et masse
[3852]738      !write(*,*) 'vlyqs 689: iq,tr%nchld=',iq,tr%nchld
[2270]739     
740      ijb=ij_begin-2*iip1
741      ije=ij_end+2*iip1
[3851]742      ijbm=ij_begin-iip1
743      ijem=ij_end+iip1
[2270]744      if (pole_nord) ijb=ij_begin
745      if (pole_sud)  ije=ij_end 
[3851]746      if (pole_nord) ijbm=ij_begin
747      if (pole_sud)  ijem=ij_end
[2270]748
[3851]749      !write(lunout,*) 'vlspltqs 737: iq,ijb,ije=',iq,ijb,ije
750      !write(lunout,*) 'ij_begin,ij_end=',ij_begin,ij_end
751      !write(lunout,*) 'pole_nord,pole_sud=',pole_nord,pole_sud
[3852]752      if(tr%ndesc > 0) then 
753       do ichld=1,tr%ndesc
754         iq2=tr%idesc(ichld)
[2270]755c$OMP DO SCHEDULE(STATIC,OMP_CHUNK)   
756         DO l=1,llm
[3851]757          ! modif des bornes: CRisi 16 nov 2020
758          ! d'abord masse avec bornes corrigées
759          DO ij=ijbm,ijem
760           !MVals: veiller a ce qu'on n'ait pas de denominateur nul
761           masse(ij,l,iq2)=max(masse(ij,l,iq)*q(ij,l,iq),masseqmin)
762          enddo !DO ij=ijbm,ijem
763
764          ! ensuite Ratio avec anciennes bornes
[2270]765          DO ij=ijb,ije
[3851]766           !MVals: veiller a ce qu'on n'ait pas de denominateur nul
767           !write(lunout,*) 'ij,l,q(ij,l,iq)=',ij,l,q(ij,l,iq)
768           if (q(ij,l,iq).gt.qperemin) then ! modif 13 nov 2020
769             Ratio(ij,l,iq2)=q(ij,l,iq2)/q(ij,l,iq)
770           else
771             Ratio(ij,l,iq2)=ratiomin   
772           endif
773          enddo !DO ij=ijbm,ijem
774         enddo !DO l=1,llm
[2270]775c$OMP END DO NOWAIT
[3852]776        enddo !do ichld=1,tr%ndesc
777        do ichld=1,tr%nchld
778         iq2=tr%idesc(ichld)
[3851]779         !write(lunout,*) 'vly: appel recursiv vly iq2=',iq2
[2281]780         call vly_loc(Ratio,pente_max,masse,qbyv,iq2)
[3852]781        enddo !do ichld=1,tr%nchld
782      endif !if(tr%ndesc > 0)
[2270]783
784       
785! end CRisi
786
[1632]787      ijb=ij_begin
788      ije=ij_end
789      if (pole_nord) ijb=ij_begin+iip1
790      if (pole_sud)  ije=ij_end-iip1
791
792c$OMP DO SCHEDULE(STATIC,OMP_CHUNK)     
793      DO l=1,llm
794         DO ij=ijb,ije
[2270]795            newmasse=masse(ij,l,iq)
[1632]796     &      +masse_adv_v(ij,l)-masse_adv_v(ij-iip1,l)
[2270]797            q(ij,l,iq)=(q(ij,l,iq)*masse(ij,l,iq)+qbyv(ij,l,iq)
798     &         -qbyv(ij-iip1,l,iq))/newmasse
799            masse(ij,l,iq)=newmasse
[1632]800         ENDDO
801c.-. ancienne version
802
803         IF (pole_nord) THEN
804
[2270]805           convpn=SSUM(iim,qbyv(1,l,iq),1)/apoln
[1632]806           convmpn=ssum(iim,masse_adv_v(1,l),1)/apoln
807           DO ij = 1,iip1
[2270]808              newmasse=masse(ij,l,iq)+convmpn*aire(ij)
809              q(ij,l,iq)=(q(ij,l,iq)*masse(ij,l,iq)+convpn*aire(ij))/
[1632]810     &                 newmasse
[2270]811              masse(ij,l,iq)=newmasse
[1632]812           ENDDO
813         
[2600]814         ENDIF
815         
816         IF (pole_sud) THEN
817         
818           convps  = -SSUM(iim,qbyv(ip1jm-iim,l,iq),iq,1)/apols
[1632]819           convmps = -SSUM(iim,masse_adv_v(ip1jm-iim,l),1)/apols
820           DO ij = ip1jm+1,ip1jmp1
[2270]821              newmasse=masse(ij,l,iq)+convmps*aire(ij)
822              q(ij,l,iq)=(q(ij,l,iq)*masse(ij,l,iq)+convps*aire(ij))/
[1632]823     &                 newmasse
[2270]824              masse(ij,l,iq)=newmasse
[1632]825           ENDDO
[2600]826         
827         ENDIF
[1632]828c.-. fin ancienne version
829
830c._. nouvelle version
[2270]831c        convpn=SSUM(iim,qbyv(1,l,iq),1)
[1632]832c        convmpn=ssum(iim,masse_adv_v(1,l),1)
[2270]833c        oldmasse=ssum(iim,masse(1,l,iq),1)
[1632]834c        newmasse=oldmasse+convmpn
[2270]835c        newq=(q(1,l,iq)*oldmasse+convpn)/newmasse
[1632]836c        newmasse=newmasse/apoln
837c        DO ij = 1,iip1
[2270]838c           q(ij,l,iq)=newq
839c           masse(ij,l,iq)=newmasse*aire(ij)
[1632]840c        ENDDO
[2270]841c        convps=-SSUM(iim,qbyv(ip1jm-iim,l,iq),1)
[1632]842c        convmps=-ssum(iim,masse_adv_v(ip1jm-iim,l),1)
[2270]843c        oldmasse=ssum(iim,masse(ip1jm-iim,l,iq),1)
[1632]844c        newmasse=oldmasse+convmps
[2270]845c        newq=(q(ip1jmp1,l,iq)*oldmasse+convps)/newmasse
[1632]846c        newmasse=newmasse/apols
847c        DO ij = ip1jm+1,ip1jmp1
[2270]848c           q(ij,l,iq)=newq
849c           masse(ij,l,iq)=newmasse*aire(ij)
[1632]850c        ENDDO
851c._. fin nouvelle version
852      ENDDO
853c$OMP END DO NOWAIT
[2270]854
855! retablir les fils en rapport de melange par rapport a l'air:
856      ijb=ij_begin
857      ije=ij_end
858!      if (pole_nord) ijb=ij_begin+iip1
859!      if (pole_sud)  ije=ij_end-iip1
860 
[3852]861      if(tr%ndesc > 0) then 
862       do ichld=1,tr%ndesc
863         iq2=tr%idesc(ichld) 
[2270]864c$OMP DO SCHEDULE(STATIC,OMP_CHUNK)   
865         DO l=1,llm
866          DO ij=ijb,ije
867            q(ij,l,iq2)=q(ij,l,iq)*Ratio(ij,l,iq2)           
868          enddo
869         enddo
870c$OMP END DO NOWAIT
[3852]871        enddo !do ichld=1,tr%ndesc
872      endif !if(tr%ndesc > 0)
[2270]873
874
[1632]875      RETURN
876      END
Note: See TracBrowser for help on using the repository browser.