source: LMDZ6/trunk/libf/dyn3dmem/vlspltqs_loc.F @ 4379

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