source: LMDZ6/trunk/libf/dyn3dmem/vlsplt_loc.F90 @ 5456

Last change on this file since 5456 was 5285, checked in by abarral, 2 months ago

As discussed internally, remove generic ONLY: ... for new _mod_h modules

  • 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: 32.6 KB
RevLine 
[1673]1!
2! $Id: vlsplt_loc.F90 5285 2024-10-28 13:33:29Z aborella $
3!
[5248]4RECURSIVE SUBROUTINE vlx_loc(q,pente_max,masse,u_m,ijb_x,ije_x,iq)
[1632]5
[5248]6  ! Auteurs:   P.Le Van, F.Hourdin, F.Forget
7  !
8  !    ********************************************************************
9  ! Shema  d'advection " pseudo amont " .
10  !    ********************************************************************
11  ! nq,iq,q,pbaru,pbarv,w sont des arguments d'entree  pour le s-pg ....
12  !
13  !
14  !   --------------------------------------------------------------------
[5282]15  USE iniprint_mod_h
[5248]16  USE parallel_lmdz
17  USE infotrac, ONLY : nqtot,tracers, & ! CRisi                 &
18        min_qParent,min_qMass,min_ratio ! MVals et CRisi
[5271]19  USE dimensions_mod, ONLY: iim, jjm, llm, ndm
[5285]20USE paramet_mod_h
[5271]21IMPLICIT NONE
[5248]22  !
[5271]23
[5272]24
[5248]25  !
26  !
27  !   Arguments:
28  !   ----------
29  REAL :: masse(ijb_u:ije_u,llm,nqtot),pente_max
30  REAL :: u_m( ijb_u:ije_u,llm),pbarv( iip1,jjb_v:jje_v,llm)
31  REAL :: q(ijb_u:ije_u,llm,nqtot) ! CRisi: ajout dimension nqtot
32  REAL :: w(ijb_u:ije_u,llm)
33  INTEGER :: iq ! CRisi
34  !
35  !  Local
36  !   ---------
37  !
38  INTEGER :: ij,l,j,i,iju,ijq,indu(ijnb_u),niju
39  INTEGER :: n0,iadvplus(ijb_u:ije_u,llm),nl(llm)
40  !
41  REAL :: new_m,zu_m,zdum(ijb_u:ije_u,llm)
42  REAL :: sigu(ijb_u:ije_u),dxq(ijb_u:ije_u,llm),dxqu(ijb_u:ije_u)
43  REAL :: zz(ijb_u:ije_u)
44  REAL :: adxqu(ijb_u:ije_u),dxqmax(ijb_u:ije_u,llm)
45  REAL :: u_mq(ijb_u:ije_u,llm)
[1632]46
[5248]47  REAL :: Ratio(ijb_u:ije_u,llm,nqtot) ! CRisi
48  INTEGER :: ifils,iq2 ! CRisi
[2270]49
[5248]50  Logical :: extremum
[1632]51
[5248]52  REAL :: SSUM
53  EXTERNAL  SSUM
[1632]54
[5248]55  REAL :: z1,z2,z3
[1632]56
[5248]57  INTEGER :: ijb,ije,ijb_x,ije_x
[1632]58
[5248]59  ! !write(*,*) 'vlsplt 58: entree dans vlx_loc, iq,ijb_x=',
60  ! &   iq,ijb_x
61  !   calcul de la pente a droite et a gauche de la maille
[1632]62
[5248]63  ijb=ijb_x
64  ije=ije_x
[1632]65
[5248]66  if (pole_nord.and.ijb==1) ijb=ijb+iip1
67  if (pole_sud.and.ije==ip1jmp1)  ije=ije-iip1
[1632]68
[5248]69  IF (pente_max.gt.-1.e-5) THEN
70    ! IF (pente_max.gt.10) THEN
[1632]71
[5248]72  !   calcul des pentes avec limitation, Van Leer scheme I:
73  !   -----------------------------------------------------
74  ! ! on a besoin de q entre ijb et ije
75  !   calcul de la pente aux points u
76!$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
77     DO l = 1, llm
[1632]78
[5248]79        DO ij=ijb,ije-1
80           dxqu(ij)=q(ij+1,l,iq)-q(ij,l,iq)
81           ! IF(u_m(ij,l).lt.0.) stop'limx n admet pas les U<0'
82           ! sigu(ij)=u_m(ij,l)/masse(ij,l,iq)
83        ENDDO
84        DO ij=ijb+iip1-1,ije,iip1
85           dxqu(ij)=dxqu(ij-iim)
86           ! sigu(ij)=sigu(ij-iim)
87        ENDDO
[1632]88
[5248]89        DO ij=ijb,ije
90           adxqu(ij)=abs(dxqu(ij))
91        ENDDO
[1632]92
[5248]93  !   calcul de la pente maximum dans la maille en valeur absolue
94
95        DO ij=ijb+1,ije
96           dxqmax(ij,l)=pente_max* &
97                 min(adxqu(ij-1),adxqu(ij))
98  ! limitation subtile
99  !    ,      min(adxqu(ij-1)/sigu(ij-1),adxqu(ij)/(1.-sigu(ij)))
100
101
102        ENDDO
103
104        DO ij=ijb+iip1-1,ije,iip1
105           dxqmax(ij-iim,l)=dxqmax(ij,l)
106        ENDDO
107
108        DO ij=ijb+1,ije
[1632]109#ifdef CRAY
[5248]110           dxq(ij,l)= &
111                 cvmgp(dxqu(ij-1)+dxqu(ij),0.,dxqu(ij-1)*dxqu(ij))
[1632]112#else
[5248]113           IF(dxqu(ij-1)*dxqu(ij).gt.0) THEN
114              dxq(ij,l)=dxqu(ij-1)+dxqu(ij)
115           ELSE
116  !   extremum local
117              dxq(ij,l)=0.
118           ENDIF
[1632]119#endif
[5248]120           dxq(ij,l)=0.5*dxq(ij,l)
121           dxq(ij,l)= &
122                 sign(min(abs(dxq(ij,l)),dxqmax(ij,l)),dxq(ij,l))
123        ENDDO
[1632]124
[5248]125     ENDDO ! l=1,llm
126!$OMP END DO NOWAIT
127  ! print*,'Ok calcul des pentes'
[1632]128
[5248]129  ELSE ! (pente_max.lt.-1.e-5)
[1632]130
[5248]131  !   Pentes produits:
132  !   ----------------
133!$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
134     DO l = 1, llm
135        DO ij=ijb,ije-1
136           dxqu(ij)=q(ij+1,l,iq)-q(ij,l,iq)
137        ENDDO
138        DO ij=ijb+iip1-1,ije,iip1
139           dxqu(ij)=dxqu(ij-iim)
140        ENDDO
[1632]141
[5248]142        DO ij=ijb+1,ije
143           zz(ij)=dxqu(ij-1)*dxqu(ij)
144           zz(ij)=zz(ij)+zz(ij)
145           IF(zz(ij).gt.0) THEN
146              dxq(ij,l)=zz(ij)/(dxqu(ij-1)+dxqu(ij))
147           ELSE
148  !   extremum local
149              dxq(ij,l)=0.
150           ENDIF
151        ENDDO
[1632]152
[5248]153     ENDDO
154!$OMP END DO NOWAIT
155  ENDIF ! (pente_max.lt.-1.e-5)
[1632]156
[5248]157  ! !write(*,*) 'vlx 156: iq,ijb_x=',iq,ijb_x
[2270]158
[5248]159  !   bouclage de la pente en iip1:
160  !   -----------------------------
161!$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
162  DO l=1,llm
163     DO ij=ijb+iip1-1,ije,iip1
164        dxq(ij-iim,l)=dxq(ij,l)
165     ENDDO
166     DO ij=ijb,ije
167        iadvplus(ij,l)=0
168     ENDDO
[1632]169
[5248]170  ENDDO
171!$OMP END DO NOWAIT
172   ! print*,'Bouclage en iip1'
[1632]173
[5248]174  !   calcul des flux a gauche et a droite
[1632]175
176#ifdef CRAY
[5248]177!$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
178  DO l=1,llm
179   DO ij=ijb,ije-1
180      zdum(ij,l)=cvmgp(1.-u_m(ij,l)/masse(ij,l,iq), &
181            1.+u_m(ij,l)/masse(ij+1,l,iq), &
182            u_m(ij,l,iq))
183      zdum(ij,l)=0.5*zdum(ij,l)
184      u_mq(ij,l)=cvmgp( &
185            q(ij,l,iq)+zdum(ij,l)*dxq(ij,l), &
186            q(ij+1,l,iq)-zdum(ij,l)*dxq(ij+1,l), &
187            u_m(ij,l))
188      u_mq(ij,l)=u_m(ij,l)*u_mq(ij,l)
189   ENDDO
190  ENDDO
191!$OMP END DO NOWAIT
[1632]192#else
[5248]193  !   on cumule le flux correspondant a toutes les mailles dont la masse
194  !   au travers de la paroi pENDant le pas de temps.
195  ! print*,'Cumule ....'
196!$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
197    ! ! on a besoin de masse entre ijb et ije
198  DO l=1,llm
199   DO ij=ijb,ije-1
200  ! print*,'masse(',ij,')=',masse(ij,l,iq)
201      IF (u_m(ij,l).gt.0.) THEN
202         zdum(ij,l)=1.-u_m(ij,l)/masse(ij,l,iq)
203         u_mq(ij,l)=u_m(ij,l)*(q(ij,l,iq) &
204               +0.5*zdum(ij,l)*dxq(ij,l))
205      ELSE
206         zdum(ij,l)=1.+u_m(ij,l)/masse(ij+1,l,iq)
207         u_mq(ij,l)=u_m(ij,l)*(q(ij+1,l,iq) &
208               -0.5*zdum(ij,l)*dxq(ij+1,l))
209      ENDIF
210   ENDDO
211  ENDDO
212!$OMP END DO NOWAIT
[1632]213#endif
214
[5248]215  ! go to 9999
216  !   detection des points ou on advecte plus que la masse de la
217  !   maille
218!$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
219  DO l=1,llm
220     DO ij=ijb,ije-1
221        IF(zdum(ij,l).lt.0) THEN
222           iadvplus(ij,l)=1
223           u_mq(ij,l)=0.
224        ENDIF
225     ENDDO
226  ENDDO
227!$OMP END DO NOWAIT
228  ! print*,'Ok test 1'
[2270]229
[5248]230!$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
231  DO l=1,llm
232   DO ij=ijb+iip1-1,ije,iip1
233      iadvplus(ij,l)=iadvplus(ij-iim,l)
234   ENDDO
235  ENDDO
236!$OMP END DO NOWAIT
237   ! print*,'Ok test 2'
[1632]238
239
[5248]240  !   traitement special pour le cas ou on advecte en longitude plus que le
241  !   contenu de la maille.
242  !   cette partie est mal vectorisee.
[1632]243
[5248]244  !  calcul du nombre de maille sur lequel on advecte plus que la maille.
[1632]245
[5248]246  n0=0
247!$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
248  DO l=1,llm
249     nl(l)=0
250     DO ij=ijb,ije
251        nl(l)=nl(l)+iadvplus(ij,l)
252     ENDDO
253     n0=n0+nl(l)
254  ENDDO
255!$OMP END DO NOWAIT
256  !ym      IF(n0.gt.1) THEN
257  !ym      IF(n0.gt.0) THEN
[2270]258
[5248]259   ! PRINT*,'Nombre de points pour lesquels on advect plus que le'
260  ! &       ,'contenu de la maille : ',n0
261!$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
[2270]262
[1632]263
[5248]264     DO l=1,llm
265        IF(nl(l).gt.0) THEN
266           iju=0
267  !   indicage des mailles concernees par le traitement special
268           DO ij=ijb,ije
269              IF(iadvplus(ij,l).eq.1.and.mod(ij,iip1).ne.0) THEN
270                 iju=iju+1
271                 indu(iju)=ij
272              ENDIF
273           ENDDO
274           niju=iju
275           ! !PRINT*,'vlx 278, niju,nl',niju,nl(l)
[1632]276
[5248]277  !  traitement des mailles
278           DO iju=1,niju
279              ij=indu(iju)
280              j=(ij-1)/iip1+1
281              zu_m=u_m(ij,l)
282              u_mq(ij,l)=0.
283              IF(zu_m.gt.0.) THEN
284                 ijq=ij
285                 i=ijq-(j-1)*iip1
286  !   accumulation pour les mailles completements advectees
287                 do while(zu_m.gt.masse(ijq,l,iq))
288                    u_mq(ij,l)=u_mq(ij,l) &
289                          +q(ijq,l,iq)*masse(ijq,l,iq)
290                    zu_m=zu_m-masse(ijq,l,iq)
291                    i=mod(i-2+iim,iim)+1
292                    ijq=(j-1)*iip1+i
293                 ENDDO
294  !   ajout de la maille non completement advectee
295                 u_mq(ij,l)=u_mq(ij,l)+zu_m* &
296                       (q(ijq,l,iq)+0.5* &
297                       (1.-zu_m/masse(ijq,l,iq))*dxq(ijq,l))
298              ELSE
299                 ijq=ij+1
300                 i=ijq-(j-1)*iip1
301  !   accumulation pour les mailles completements advectees
302                 do while(-zu_m.gt.masse(ijq,l,iq))
303                    u_mq(ij,l)=u_mq(ij,l)-q(ijq,l,iq) &
304                          *masse(ijq,l,iq)
305                    zu_m=zu_m+masse(ijq,l,iq)
306                    i=mod(i,iim)+1
307                    ijq=(j-1)*iip1+i
308                 ENDDO
309  !   ajout de la maille non completement advectee
310                 u_mq(ij,l)=u_mq(ij,l)+zu_m*(q(ijq,l,iq)- &
311                       0.5*(1.+zu_m/masse(ijq,l,iq))*dxq(ijq,l))
312              ENDIF
313           ENDDO
314        ENDIF
315     ENDDO
316!$OMP END DO NOWAIT
317  !ym      ENDIF  ! n0.gt.0
3189999   continue
[1632]319
[5248]320  !   bouclage en latitude
321  ! print*,'Avant bouclage en latitude'
322!$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
323  DO l=1,llm
324    DO ij=ijb+iip1-1,ije,iip1
325       u_mq(ij,l)=u_mq(ij-iim,l)
326    ENDDO
327  ENDDO
328!$OMP END DO NOWAIT
[2270]329
[5248]330  ! CRisi: appel récursif de l'advection sur les fils.
331  ! Il faut faire ça avant d'avoir mis à jour q et masse
332
333  do ifils=1,tracers(iq)%nqDescen
334    ! ! attention: comme Ratio est utilisé comme q dans l'appel
335    ! ! recursif, il doit contenir à lui seul tous les indices de tous
336    ! ! les descendants!
337    iq2=tracers(iq)%iqDescen(ifils)
338!$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
339    DO l=1,llm
340      DO ij=ijb,ije
341        ! ! On a besoin de q et masse seulement entre ijb et ije. On ne
342        ! ! les calcule donc que de ijb à ije
343        ! !MVals: veiller a ce qu'on n'ait pas de denominateur nul
344        masse(ij,l,iq2)=max(masse(ij,l,iq)*q(ij,l,iq),min_qMass)
345        if (q(ij,l,iq).gt.min_qParent) then ! modif 13 nov 2020
346          Ratio(ij,l,iq2)=q(ij,l,iq2)/q(ij,l,iq)
347        else
348          Ratio(ij,l,iq2)=min_ratio
349        endif
[4050]350      enddo
[5248]351    enddo
352!$OMP END DO NOWAIT
353  enddo !do ifils=1,tracers(iq)%nqDescen
354  do ifils=1,tracers(iq)%nqChildren
355    iq2=tracers(iq)%iqDescen(ifils)
356    call vlx_loc(Ratio,pente_max,masse,u_mq,ijb_x,ije_x,iq2)
357  enddo
358  ! end CRisi
[2270]359
360
[5248]361  !   calcul des tENDances
362!$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
363  DO l=1,llm
364     DO ij=ijb+1,ije
365        ! !MVals: veiller a ce qu'on n'ait pas de denominateur nul
366        new_m=max(masse(ij,l,iq)+u_m(ij-1,l)-u_m(ij,l),min_qMass)
367        q(ij,l,iq)=(q(ij,l,iq)*masse(ij,l,iq)+ &
368              u_mq(ij-1,l)-u_mq(ij,l)) &
369              /new_m
370        masse(ij,l,iq)=new_m
371     ENDDO
372  !   ModIF Fred 22 03 96 correction d'un bug (les scopy ci-dessous)
373     DO ij=ijb+iip1-1,ije,iip1
374        q(ij-iim,l,iq)=q(ij,l,iq)
375        masse(ij-iim,l,iq)=masse(ij,l,iq)
376     ENDDO
377  ENDDO
378!$OMP END DO NOWAIT
[2270]379
[5248]380  ! retablir les fils en rapport de melange par rapport a l'air:
381  ! ! On calcule q entre ijb+1 et ije -> on fait pareil pour ratio
382  ! ! puis on boucle en longitude
383  do ifils=1,tracers(iq)%nqDescen
384    iq2=tracers(iq)%iqDescen(ifils)
385!$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)
[4050]389      enddo
[5248]390      DO ij=ijb+iip1-1,ije,iip1
391        q(ij-iim,l,iq2)=q(ij,l,iq2)
392      enddo
393    enddo
394!$OMP END DO NOWAIT
395  enddo
[2270]396
[5248]397  ! !write(*,*) 'vlsplt 399: iq,ijb_x=',iq,ijb_x
398  ! CALL SCOPY((jjm-1)*llm,q(iip1+iip1,1),iip1,q(iip2,1),iip1)
399  ! CALL SCOPY((jjm-1)*llm,masse(iip1+iip1,1),iip1,masse(iip2,1),iip1)
[1632]400
401
[5248]402  RETURN
403END SUBROUTINE vlx_loc
[1632]404
405
[5248]406RECURSIVE SUBROUTINE vly_loc(q,pente_max,masse,masse_adv_v,iq)
407  !
408  ! Auteurs:   P.Le Van, F.Hourdin, F.Forget
409  !
410  !    ********************************************************************
411  ! Shema  d'advection " pseudo amont " .
412  !    ********************************************************************
413  ! q,masse_adv_v,w sont des arguments d'entree  pour le s-pg ....
414  ! dq         sont des arguments de sortie pour le s-pg ....
415  !
416  !
417  !   --------------------------------------------------------------------
[5281]418  USE comgeom_mod_h
[5248]419  USE parallel_lmdz
420  USE infotrac, ONLY : nqtot,tracers, & ! CRisi                 &
421        min_qParent,min_qMass,min_ratio ! MVals et CRisi
422  USE comconst_mod, ONLY: pi
[5271]423  USE dimensions_mod, ONLY: iim, jjm, llm, ndm
[5285]424USE paramet_mod_h
[5271]425IMPLICIT NONE
[5248]426  !
[5271]427
[5272]428
[5248]429  !
430  !
431  !   Arguments:
432  !   ----------
433  REAL :: masse(ijb_u:ije_u,llm,nqtot),pente_max
434  REAL :: masse_adv_v( ijb_v:ije_v,llm)
435  REAL :: q(ijb_u:ije_u,llm,nqtot), dq( ijb_u:ije_u,llm)
436  INTEGER :: iq ! CRisi
437  !
438  !  Local
439  !   ---------
440  !
441  INTEGER :: i,ij,l
442  !
443  REAL :: airej2,airejjm,airescb(iim),airesch(iim)
444  REAL :: dyq(ijb_u:ije_u,llm),dyqv(ijb_v:ije_v),zdvm(ijb_u:ije_u,llm)
445  REAL :: adyqv(ijb_v:ije_v),dyqmax(ijb_u:ije_u)
446  REAL :: qbyv(ijb_v:ije_v,llm)
[1632]447
[5248]448  REAL :: qpns,qpsn,appn,apps,dyn1,dys1,dyn2,dys2,newmasse,fn,fs
449  ! REAL newq,oldmasse
450  Logical :: extremum,first,testcpu
451  REAL :: temps0,temps1,temps2,temps3,temps4,temps5,second
452  SAVE temps0,temps1,temps2,temps3,temps4,temps5
453!$OMP THREADPRIVATE(temps0,temps1,temps2,temps3,temps4,temps5)
454  SAVE first,testcpu
455!$OMP THREADPRIVATE(first,testcpu)
[1632]456
[5248]457  REAL :: convpn,convps,convmpn,convmps
458  real :: massepn,masseps,qpn,qps
459  REAL :: sinlon(iip1),sinlondlon(iip1)
460  REAL :: coslon(iip1),coslondlon(iip1)
461  SAVE sinlon,coslon,sinlondlon,coslondlon
462!$OMP THREADPRIVATE(sinlon,coslon,sinlondlon,coslondlon)
463  SAVE airej2,airejjm
464!$OMP THREADPRIVATE(airej2,airejjm)
[2270]465
[5248]466  REAL :: Ratio(ijb_u:ije_u,llm,nqtot) ! CRisi
467  INTEGER :: ifils,iq2 ! CRisi
468  !
469  !
470  REAL :: SSUM
471  EXTERNAL  SSUM
[1632]472
[5248]473  DATA first,testcpu/.true.,.false./
474  DATA temps0,temps1,temps2,temps3,temps4,temps5/0.,0.,0.,0.,0.,0./
475  INTEGER :: ijb,ije
476  INTEGER :: ijbm,ijem
[1632]477
[5248]478  ijb=ij_begin-2*iip1
479  ije=ij_end+2*iip1
480  if (pole_nord) ijb=ij_begin
481  if (pole_sud)  ije=ij_end
[2270]482
[5248]483  IF(first) THEN
484     PRINT*,'Shema  Amont nouveau  appele dans  Vanleer   '
485     first=.false.
486     do i=2,iip1
487        coslon(i)=cos(rlonv(i))
488        sinlon(i)=sin(rlonv(i))
489        coslondlon(i)=coslon(i)*(rlonu(i)-rlonu(i-1))/pi
490        sinlondlon(i)=sinlon(i)*(rlonu(i)-rlonu(i-1))/pi
491     ENDDO
492     coslon(1)=coslon(iip1)
493     coslondlon(1)=coslondlon(iip1)
494     sinlon(1)=sinlon(iip1)
495     sinlondlon(1)=sinlondlon(iip1)
496     airej2 = SSUM( iim, aire(iip2), 1 )
497     airejjm= SSUM( iim, aire(ip1jm -iim), 1 )
498  ENDIF
[1632]499
[5248]500  !
501  ! PRINT*,'CALCUL EN LATITUDE'
[1632]502
[5248]503!$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
504  DO l = 1, llm
505  !
506  !   --------------------------------
507  !  CALCUL EN LATITUDE
508  !   --------------------------------
[1632]509
[5248]510  !   On commence par calculer la valeur du traceur moyenne sur le premier cercle
511  !   de latitude autour du pole (qpns pour le pole nord et qpsn pour
512  !    le pole nord) qui sera utilisee pour evaluer les pentes au pole.
[1632]513
[5248]514  if (pole_nord) then
515    DO i = 1, iim
516      airescb(i) = aire(i+ iip1) * q(i+ iip1,l,iq)
517    ENDDO
518    qpns   = SSUM( iim,  airescb ,1 ) / airej2
519  endif
[1632]520
[5248]521  if (pole_sud) then
522    DO i = 1, iim
523      airesch(i) = aire(i+ ip1jm- iip1) * q(i+ ip1jm- iip1,l,iq)
524    ENDDO
525    qpsn   = SSUM( iim,  airesch ,1 ) / airejjm
526  endif
[1632]527
[5248]528  !   calcul des pentes aux points v
[1632]529
[5248]530  ijb=ij_begin-2*iip1
531  ije=ij_end+iip1
532  if (pole_nord) ijb=ij_begin
533  if (pole_sud)  ije=ij_end-iip1
[1632]534
[5248]535  ! ! on a besoin de q entre ij_begin-2*iip1 et ij_end+2*iip1
536  ! ! Si pole sud, entre ij_begin-2*iip1 et ij_end
537  ! ! Si pole Nord, entre ij_begin et ij_end+2*iip1
538  DO ij=ijb,ije
539     dyqv(ij)=q(ij,l,iq)-q(ij+iip1,l,iq)
540     adyqv(ij)=abs(dyqv(ij))
541  ENDDO
[1632]542
543
[5248]544  !   calcul des pentes aux points scalaires
545  ijb=ij_begin-iip1
546  ije=ij_end+iip1
547  if (pole_nord) ijb=ij_begin+iip1
548  if (pole_sud)  ije=ij_end-iip1
[1632]549
[5248]550  DO ij=ijb,ije
551     dyq(ij,l)=.5*(dyqv(ij-iip1)+dyqv(ij))
552     dyqmax(ij)=min(adyqv(ij-iip1),adyqv(ij))
553     dyqmax(ij)=pente_max*dyqmax(ij)
554  ENDDO
[1632]555
[5248]556  !   calcul des pentes aux poles
557  IF (pole_nord) THEN
558    DO ij=1,iip1
559       dyq(ij,l)=qpns-q(ij+iip1,l,iq)
560    ENDDO
[1632]561
[5248]562    dyn1=0.
563    dyn2=0.
564    DO ij=1,iim
565      dyn1=dyn1+sinlondlon(ij)*dyq(ij,l)
566      dyn2=dyn2+coslondlon(ij)*dyq(ij,l)
567    ENDDO
568    DO ij=1,iip1
569      dyq(ij,l)=dyn1*sinlon(ij)+dyn2*coslon(ij)
570    ENDDO
[1632]571
[5248]572    DO ij=1,iip1
573     dyq(ij,l)=0.
574    ENDDO
575  ! ym tout cela ne sert pas a grand chose
576  ENDIF
[1632]577
[5248]578  IF (pole_sud) THEN
[1632]579
[5248]580    DO ij=1,iip1
581       dyq(ip1jm+ij,l)=q(ip1jm+ij-iip1,l,iq)-qpsn
582    ENDDO
[1632]583
[5248]584    dys1=0.
585    dys2=0.
[1632]586
[5248]587    DO ij=1,iim
588      dys1=dys1+sinlondlon(ij)*dyq(ip1jm+ij,l)
589      dys2=dys2+coslondlon(ij)*dyq(ip1jm+ij,l)
590    ENDDO
[1632]591
[5248]592    DO ij=1,iip1
593      dyq(ip1jm+ij,l)=dys1*sinlon(ij)+dys2*coslon(ij)
594    ENDDO
[2270]595
[5248]596    DO ij=1,iip1
597     dyq(ip1jm+ij,l)=0.
598    ENDDO
599  ! ym tout cela ne sert pas a grand chose
600  ENDIF
[2270]601
[5248]602  !   filtrage de la derivee
[3800]603
[5248]604  !   calcul des pentes limites aux poles
605  ! ym partie inutile
606   ! goto 8888
607   ! fn=1.
608   ! fs=1.
609   ! DO ij=1,iim
610   !    IF(pente_max*adyqv(ij).lt.abs(dyq(ij,l))) THEN
611   !       fn=min(pente_max*adyqv(ij)/abs(dyq(ij,l)),fn)
612   !    ENDIF
613   ! IF(pente_max*adyqv(ij+ip1jm-iip1).lt.abs(dyq(ij+ip1jm,l))) THEN
614   !    fs=min(pente_max*adyqv(ij+ip1jm-iip1)/abs(dyq(ij+ip1jm,l)),fs)
615   !    ENDIF
616   ! ENDDO
617   ! DO ij=1,iip1
618   !    dyq(ij,l)=fn*dyq(ij,l)
619   !    dyq(ip1jm+ij,l)=fs*dyq(ip1jm+ij,l)
620   ! ENDDO
621  ! 8888    continue
[3800]622
[2270]623
[5248]624  !CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
625  !  En memoire de dIFferents tests sur la
626  !  limitation des pentes aux poles.
627  !CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
628  ! PRINT*,dyq(1)
629  ! PRINT*,dyqv(iip1+1)
630  ! appn=abs(dyq(1)/dyqv(iip1+1))
631  ! PRINT*,dyq(ip1jm+1)
632  ! PRINT*,dyqv(ip1jm-iip1+1)
633  ! apps=abs(dyq(ip1jm+1)/dyqv(ip1jm-iip1+1))
634  ! DO ij=2,iim
635  !    appn=amax1(abs(dyq(ij)/dyqv(ij)),appn)
636  !    apps=amax1(abs(dyq(ip1jm+ij)/dyqv(ip1jm-iip1+ij)),apps)
637  ! ENDDO
638  ! appn=min(pente_max/appn,1.)
639  ! apps=min(pente_max/apps,1.)
640  !
641  !
642  !   cas ou on a un extremum au pole
643  !
644  ! IF(dyqv(ismin(iim,dyqv,1))*dyqv(ismax(iim,dyqv,1)).le.0.)
645  !    &   appn=0.
646  ! IF(dyqv(ismax(iim,dyqv(ip1jm-iip1+1),1)+ip1jm-iip1+1)*
647  !    &   dyqv(ismin(iim,dyqv(ip1jm-iip1+1),1)+ip1jm-iip1+1).le.0.)
648  !    &   apps=0.
649  !
650  !   limitation des pentes aux poles
651  ! DO ij=1,iip1
652  !    dyq(ij)=appn*dyq(ij)
653  !    dyq(ip1jm+ij)=apps*dyq(ip1jm+ij)
654  ! ENDDO
655  !
656  !   test
657  !  DO ij=1,iip1
658  !     dyq(iip1+ij)=0.
659  !     dyq(ip1jm+ij-iip1)=0.
660  !  ENDDO
661  !  DO ij=1,ip1jmp1
662  !     dyq(ij)=dyq(ij)*cos(rlatu((ij-1)/iip1+1))
663  !  ENDDO
664  !
665  ! changement 10 07 96
666  ! IF(dyqv(ismin(iim,dyqv,1))*dyqv(ismax(iim,dyqv,1)).le.0.)
667  !    &   THEN
668  !    DO ij=1,iip1
669  !       dyqmax(ij)=0.
670  !    ENDDO
671  ! ELSE
672  !    DO ij=1,iip1
673  !       dyqmax(ij)=pente_max*abs(dyqv(ij))
674  !    ENDDO
675  ! ENDIF
676  !
677  ! IF(dyqv(ismax(iim,dyqv(ip1jm-iip1+1),1)+ip1jm-iip1+1)*
678  !    & dyqv(ismin(iim,dyqv(ip1jm-iip1+1),1)+ip1jm-iip1+1).le.0.)
679  !    &THEN
680  !    DO ij=ip1jm+1,ip1jmp1
681  !       dyqmax(ij)=0.
682  !    ENDDO
683  ! ELSE
684  !    DO ij=ip1jm+1,ip1jmp1
685  !       dyqmax(ij)=pente_max*abs(dyqv(ij-iip1))
686  !    ENDDO
687  ! ENDIF
688  !   fin changement 10 07 96
689  !CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
690
691  !   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
706!$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
713!$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
717          qbyv(ij,l)=q(ij+iip1,l,iq)+dyq(ij+iip1,l)* &
718                0.5*(1.-masse_adv_v(ij,l) &
719                /masse(ij+iip1,l,iq))
720      ELSE
721          qbyv(ij,l)=q(ij,l,iq)-dyq(ij,l)* &
722                0.5*(1.+masse_adv_v(ij,l)/masse(ij,l,iq))
723      ENDIF
724      qbyv(ij,l)=masse_adv_v(ij,l)*qbyv(ij,l)
725   ENDDO
726  ENDDO
727!$OMP END DO NOWAIT
728
729  ! CRisi: appel récursif de l'advection sur les fils.
730  ! Il faut faire ça avant d'avoir mis à jour q et masse
731  ! write(*,*)'vly 689: iq,nqChildren(iq)=',iq,tracers(iq)%nqChildren
732
733  ijb=ij_begin-2*iip1
734  ije=ij_end+2*iip1
735  ijbm=ij_begin-iip1
736  ijem=ij_end+iip1
737  if (pole_nord) ijb=ij_begin
738  if (pole_sud)  ije=ij_end
739  if (pole_nord) ijbm=ij_begin
740  if (pole_sud)  ijem=ij_end
741
742  do ifils=1,tracers(iq)%nqDescen
743    iq2=tracers(iq)%iqDescen(ifils)
744!$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
745    DO l=1,llm
746    ! ! modif des bornes: CRisi 16 nov 2020
747    ! ! d'abord masse avec bornes corrigées
748      DO ij=ijbm,ijem
749      ! !MVals: veiller a ce qu'on n'ait pas de denominateur nul
750        masse(ij,l,iq2)=max(masse(ij,l,iq)*q(ij,l,iq),min_qMass)
[4050]751      enddo
[2270]752
[5248]753      ! ! ensuite Ratio avec anciennes bornes
754      DO ij=ijb,ije
755      ! !MVals: veiller a ce qu'on n'ait pas de denominateur nul
756        if (q(ij,l,iq).gt.min_qParent) then ! modif 13 nov 2020
757          Ratio(ij,l,iq2)=q(ij,l,iq2)/q(ij,l,iq)
758        else
759          Ratio(ij,l,iq2)=min_ratio
760        endif
761      enddo !DO ij=ijbm,ijem
762    enddo !DO l=1,llm
763!$OMP END DO NOWAIT
764  enddo
[2270]765
[5248]766  do ifils=1,tracers(iq)%nqChildren
767    iq2=tracers(iq)%iqDescen(ifils)
768    call vly_loc(Ratio,pente_max,masse,qbyv,iq2)
769  enddo
770  ! end CRisi
[2270]771
[5248]772  ijb=ij_begin
773  ije=ij_end
774  if (pole_nord) ijb=ij_begin+iip1
775  if (pole_sud)  ije=ij_end-iip1
[2270]776
[5248]777!$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
778  DO l=1,llm
779     DO ij=ijb,ije
780        newmasse=masse(ij,l,iq) &
781              +masse_adv_v(ij,l)-masse_adv_v(ij-iip1,l)
[2270]782
[5248]783        q(ij,l,iq)=(q(ij,l,iq)*masse(ij,l,iq)+qbyv(ij,l) &
784              -qbyv(ij-iip1,l))/newmasse
[1632]785
[5248]786        masse(ij,l,iq)=newmasse
[1632]787
[5248]788     ENDDO
[2270]789
[5248]790
791  !.-. ancienne version
792     ! convpn=SSUM(iim,qbyv(1,l),1)/apoln
793     ! convmpn=ssum(iim,masse_adv_v(1,l),1)/apoln
794     if (pole_nord) then
795       convpn=SSUM(iim,qbyv(1,l),1)
796       convmpn=ssum(iim,masse_adv_v(1,l),1)
797       massepn=ssum(iim,masse(1,l,iq),1)
798       qpn=0.
799       do ij=1,iim
800          qpn=qpn+masse(ij,l,iq)*q(ij,l,iq)
801       enddo
802       qpn=(qpn+convpn)/(massepn+convmpn)
803       do ij=1,iip1
804          q(ij,l,iq)=qpn
805       enddo
806     endif
807
808     ! convps=-SSUM(iim,qbyv(ip1jm-iim,l),1)/apols
809     ! convmps=-ssum(iim,masse_adv_v(ip1jm-iim,l),1)/apols
810
811     if (pole_sud) then
812
813       convps=-SSUM(iim,qbyv(ip1jm-iim,l),1)
814       convmps=-ssum(iim,masse_adv_v(ip1jm-iim,l),1)
815       masseps=ssum(iim, masse(ip1jm+1,l,iq),1)
816       qps=0.
817       do ij = ip1jm+1,ip1jmp1-1
818          qps=qps+masse(ij,l,iq)*q(ij,l,iq)
819       enddo
820       qps=(qps+convps)/(masseps+convmps)
821       do ij=ip1jm+1,ip1jmp1
822          q(ij,l,iq)=qps
823       enddo
824     endif
825  !.-. fin ancienne version
826
827  !._. nouvelle version
828     ! convpn=SSUM(iim,qbyv(1,l),1)
829     ! convmpn=ssum(iim,masse_adv_v(1,l),1)
830     ! oldmasse=ssum(iim,masse(1,l),1)
831     ! newmasse=oldmasse+convmpn
832     ! newq=(q(1,l)*oldmasse+convpn)/newmasse
833     ! newmasse=newmasse/apoln
834     ! DO ij = 1,iip1
835     !    q(ij,l)=newq
836     !    masse(ij,l,iq)=newmasse*aire(ij)
837     ! ENDDO
838     ! convps=-SSUM(iim,qbyv(ip1jm-iim,l),1)
839     ! convmps=-ssum(iim,masse_adv_v(ip1jm-iim,l),1)
840     ! oldmasse=ssum(iim,masse(ip1jm-iim,l),1)
841     ! newmasse=oldmasse+convmps
842     ! newq=(q(ip1jmp1,l)*oldmasse+convps)/newmasse
843     ! newmasse=newmasse/apols
844     ! DO ij = ip1jm+1,ip1jmp1
845     !    q(ij,l)=newq
846     !    masse(ij,l,iq)=newmasse*aire(ij)
847     ! ENDDO
848  !._. fin nouvelle version
849  ENDDO
850!$OMP END DO NOWAIT
851
852  ! retablir les fils en rapport de melange par rapport a l'air:
853  ijb=ij_begin
854  ije=ij_end
855   ! if (pole_nord) ijb=ij_begin
856   ! if (pole_sud)  ije=ij_end
857
858  do ifils=1,tracers(iq)%nqDescen
859    iq2=tracers(iq)%iqDescen(ifils)
860!$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
861    DO l=1,llm
862      DO ij=ijb,ije
863        q(ij,l,iq2)=q(ij,l,iq)*Ratio(ij,l,iq2)
[4050]864      enddo
[5248]865    enddo
866!$OMP END DO NOWAIT
867  enddo
[2270]868
869
[5248]870  RETURN
871END SUBROUTINE vly_loc
[2765]872
[5248]873
874
875RECURSIVE SUBROUTINE vlz_loc(q,pente_max,masse,w,ijb_x,ije_x,iq)
876  !
877  ! Auteurs:   P.Le Van, F.Hourdin, F.Forget
878  !
879  !    ********************************************************************
880  ! Shema  d'advection " pseudo amont " .
881  !    ********************************************************************
882  !    q,pbaru,pbarv,w sont des arguments d'entree  pour le s-pg ....
883  ! dq         sont des arguments de sortie pour le s-pg ....
884  !
885  !
886  !   --------------------------------------------------------------------
[5282]887  USE iniprint_mod_h
[5248]888  USE parallel_lmdz
889  USE vlz_mod
890  USE infotrac, ONLY : nqtot,tracers, & ! CRisi                 &
891        min_qParent,min_qMass,min_ratio ! MVals et CRisi
892
[5271]893  USE dimensions_mod, ONLY: iim, jjm, llm, ndm
[5285]894USE paramet_mod_h
[5271]895IMPLICIT NONE
[5248]896  !
[5271]897
[5272]898
[5248]899  !
900  !
901  !   Arguments:
902  !   ----------
903  REAL :: masse(ijb_u:ije_u,llm,nqtot),pente_max
904  REAL :: q(ijb_u:ije_u,llm,nqtot)
905  REAL :: w(ijb_u:ije_u,llm+1,nqtot)
906  INTEGER :: iq
907  !
908  !  Local
909  !   ---------
910  !
911  INTEGER :: i,ij,l,j,ii
912
913  REAL,DIMENSION(ijb_u:ije_u,llm+1) :: wresi,morig,qorig,dzqorig
914  INTEGER,DIMENSION(ijb_u:ije_u,llm+1) :: lorig
915  INTEGER,SAVE :: countcfl
[2765]916!$OMP THREADPRIVATE(countcfl)
[5248]917  !
918  REAL :: newmasse
[1632]919
[5248]920  REAL :: dzqmax
921  REAL :: sigw
[1632]922
[5248]923  LOGICAL :: testcpu
924  SAVE testcpu
925!$OMP THREADPRIVATE(testcpu)
926  REAL :: temps0,temps1,temps2,temps3,temps4,temps5,second
927  SAVE temps0,temps1,temps2,temps3,temps4,temps5
928!$OMP THREADPRIVATE(temps0,temps1,temps2,temps3,temps4,temps5)
[1632]929
[5248]930  REAL :: SSUM
931  EXTERNAL  SSUM
[1632]932
[5248]933  DATA testcpu/.false./
934  DATA temps0,temps1,temps2,temps3,temps4,temps5/0.,0.,0.,0.,0.,0./
935  INTEGER :: ijb,ije,ijb_x,ije_x
936  LOGICAL,SAVE :: first=.TRUE.
[1632]937!$OMP THREADPRIVATE(first)
938
[5248]939  ! !REAL masseq(ijb_u:ije_u,llm,nqtot),Ratio(ijb_u:ije_u,llm,nqtot) ! CRisi
940  ! ! Ces varibles doivent être déclarées en pointer et en save dans
941  ! ! vlz_loc si on veut qu'elles soient vues par tous les threads.
942  INTEGER :: ifils,iq2 ! CRisi
[2270]943
[2765]944
[5248]945  IF (first) THEN
946   first=.FALSE.
947  ENDIF
948  !    On oriente tout dans le sens de la pression c'est a dire dans le
949  !    sens de W
[1632]950
[5248]951  ! !write(*,*) 'vlsplt 926: entree dans vlz_loc, iq=',iq
[1632]952#ifdef BIDON
[5248]953  IF(testcpu) THEN
954     temps0=second(0.)
955  ENDIF
[1632]956#endif
957
[5248]958  ijb=ijb_x
959  ije=ije_x
[1632]960
[5248]961!$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
962  DO l=2,llm
963     DO ij=ijb,ije
964        dzqw(ij,l)=q(ij,l-1,iq)-q(ij,l,iq)
965        adzqw(ij,l)=abs(dzqw(ij,l))
966     ENDDO
967  ENDDO
968!$OMP END DO
[1632]969
[5248]970!$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
971  DO l=2,llm-1
972     DO ij=ijb,ije
[1632]973#ifdef CRAY
[5248]974        dzq(ij,l)=0.5* &
975              cvmgp(dzqw(ij,l)+dzqw(ij,l+1),0.,dzqw(ij,l)*dzqw(ij,l+1))
[1632]976#else
[5248]977        IF(dzqw(ij,l)*dzqw(ij,l+1).gt.0.) THEN
978            dzq(ij,l)=0.5*(dzqw(ij,l)+dzqw(ij,l+1))
979        ELSE
980            dzq(ij,l)=0.
981        ENDIF
[1632]982#endif
[5248]983        dzqmax=pente_max*min(adzqw(ij,l),adzqw(ij,l+1))
984        dzq(ij,l)=sign(min(abs(dzq(ij,l)),dzqmax),dzq(ij,l))
985     ENDDO
986  ENDDO
987!$OMP END DO NOWAIT
[1632]988
[5248]989!$OMP MASTER
990  DO ij=ijb,ije
991     dzq(ij,1)=0.
992     dzq(ij,llm)=0.
993  ENDDO
994!$OMP END MASTER
995!$OMP BARRIER
[1632]996#ifdef BIDON
[5248]997  IF(testcpu) THEN
998     temps1=temps1+second(0.)-temps0
999  ENDIF
[1632]1000#endif
[2765]1001
[5248]1002  !--------------------------------------------------------
1003  ! On repere les points qui violent le CFL (|w| > masse)
1004  !--------------------------------------------------------
[2765]1005
[5248]1006  countcfl=0
1007  ! print*,'vlz nouveau'
1008!$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
1009  DO l = 2,llm
1010     DO ij = ijb,ije
1011      IF(  (w(ij,l,iq)>0.AND.w(ij,l,iq)>masse(ij,l,iq)) &
1012            .OR. (w(ij,l,iq)<=0.AND.ABS(w(ij,l,iq))>masse(ij,l-1,iq)) ) &
1013            countcfl=countcfl+1
1014     ENDDO
1015  ENDDO
1016!$OMP END DO NOWAIT
[2765]1017
[5248]1018  ! ---------------------------------------------------------------
1019  !  Identification des mailles ou on viole le CFL : w > masse
1020  ! ---------------------------------------------------------------
[2765]1021
[5248]1022  IF (countcfl==0) THEN
[2765]1023
[5248]1024  ! ---------------------------------------------------------------
1025  !   .... calcul des termes d'advection verticale  .......
1026  ! Dans le cas où le  |w| < masse partout.
1027  ! Version d'origine
1028  ! Pourrait etre enleve si on voit que le code plus general
1029  ! est aussi rapide
1030  ! ---------------------------------------------------------------
[1632]1031
[5248]1032  ! calcul de  - d( q   * w )/ d(sigma)    qu'on ajoute a  dq pour calculer dq
[1632]1033
[5248]1034  !  !write(*,*) 'vlz 982,ijb,ije=',ijb,ije
1035!$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
1036   DO l = 1,llm-1
1037     do  ij = ijb,ije
1038      IF(w(ij,l+1,iq).gt.0.) THEN
1039         sigw=w(ij,l+1,iq)/masse(ij,l+1,iq)
1040         wq(ij,l+1,iq)=w(ij,l+1,iq)*(q(ij,l+1,iq) &
1041               +0.5*(1.-sigw)*dzq(ij,l+1))
1042      ELSE
1043         sigw=w(ij,l+1,iq)/masse(ij,l,iq)
1044         wq(ij,l+1,iq)=w(ij,l+1,iq)*(q(ij,l,iq) &
1045               -0.5*(1.+sigw)*dzq(ij,l))
1046      ENDIF
1047     ENDDO
1048   ENDDO
1049!$OMP END DO NOWAIT
1050   ! !write(*,*) 'vlz 1001'
[1632]1051
[5248]1052  ELSE ! countcfl>=1
[2765]1053
[5248]1054  IF (prt_level>9) THEN
1055    WRITE(lunout,*)'vlz passage dans le non local'
1056  ENDIF
1057  ! ---------------------------------------------------------------
1058  !  Debut du traitement du cas ou on viole le CFL : w > masse
1059  ! ---------------------------------------------------------------
[2765]1060
[5248]1061  ! Initialisation
[2765]1062
[5248]1063!$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
1064   DO l = 2,llm
1065     DO ij = ijb,ije
1066        wresi(ij,l)=w(ij,l,iq)
1067        wq(ij,l,iq)=0.
1068        IF(w(ij,l,iq).gt.0.) THEN
1069           lorig(ij,l)=l
1070           morig(ij,l)=masse(ij,l,iq)
1071           qorig(ij,l)=q(ij,l,iq)
1072           dzqorig(ij,l)=dzq(ij,l)
1073        ELSE
1074           lorig(ij,l)=l-1
1075           morig(ij,l)=masse(ij,l-1,iq)
1076           qorig(ij,l)=q(ij,l-1,iq)
1077           dzqorig(ij,l)=dzq(ij,l-1)
[3435]1078        ENDIF
[5248]1079     ENDDO
1080   ENDDO
1081!$OMP END DO NOWAIT
[2765]1082
[5248]1083  ! Reindicage vertical en accumulant les flux sur
1084  !  les mailles qui viollent le CFL
1085  !  on itère jusqu'à ce que tous les poins satisfassent
1086  !  le critère
1087  DO WHILE (countcfl>=1)
1088    IF (prt_level>9) THEN
1089      WRITE(lunout,*)'On viole le CFL Vertical sur ',countcfl,' pts'
1090    ENDIF
1091  countcfl=0
[2765]1092
[5248]1093!$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
1094  DO l = 2,llm
1095     DO ij = ijb,ije
1096      IF (ABS(wresi(ij,l))>morig(ij,l)) THEN
1097         countcfl=countcfl+1
1098  ! rm : les 8 lignes ci dessous pourraient sans doute s'ecrire
1099  ! avec la fonction sign
1100         IF(w(ij,l,iq)>0.) THEN
1101            wresi(ij,l)=wresi(ij,l)-morig(ij,l)
1102            wq(ij,l,iq)=wq(ij,l,iq)+morig(ij,l)*qorig(ij,l)
1103            lorig(ij,l)=lorig(ij,l)+1
1104         ELSE
1105            wresi(ij,l)=wresi(ij,l)+morig(ij,l)
1106            wq(ij,l,iq)=wq(ij,l,iq)-morig(ij,l)*qorig(ij,l)
1107            lorig(ij,l)=lorig(ij,l)-1
1108         ENDIF
1109         ! ! CRisi 24nov2020: ajout d'un message d'erreur clair au lieu d'un plantage
1110         ! ! pour seg fault
1111         if (lorig(ij,l).eq.0) then
1112            call abort_gcm("vlz in vlsplt_loc", &
1113                  "unfixable violation of CFL",1)
1114         endif
1115         morig(ij,l)=masse(ij,lorig(ij,l),iq)
1116         qorig(ij,l)=q(ij,lorig(ij,l),iq)
1117         dzqorig(ij,l)=dzq(ij,lorig(ij,l))
1118      ENDIF
1119     ENDDO
1120  ENDDO
1121!$OMP END DO NOWAIT
[2765]1122
[5248]1123  ENDDO ! WHILE (countcfl>=1)
[2765]1124
[5248]1125!$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
1126   DO l = 2,llm
1127     do  ij = ijb,ije
1128      sigw=wresi(ij,l)/morig(ij,l)
1129      IF(w(ij,l,iq).gt.0.) THEN
1130         wq(ij,l,iq)=wq(ij,l,iq)+wresi(ij,l)*(qorig(ij,l) &
1131               +0.5*(1.-sigw)*dzqorig(ij,l))
1132      ELSE
1133         wq(ij,l,iq)=wq(ij,l,iq)+wresi(ij,l)*(qorig(ij,l) &
1134               -0.5*(1.+sigw)*dzqorig(ij,l))
1135      ENDIF
1136     ENDDO
1137   ENDDO
1138!$OMP END DO NOWAIT
[2765]1139
1140
[5248]1141   ENDIF ! councfl=0
[2765]1142
1143
[1632]1144
[5248]1145!$OMP MASTER
1146   DO ij=ijb,ije
1147      wq(ij,llm+1,iq)=0.
1148      wq(ij,1,iq)=0.
1149   ENDDO
1150!$OMP END MASTER
1151!$OMP BARRIER
[2281]1152
[5248]1153  ! CRisi: appel récursif de l'advection sur les fils.
1154  ! Il faut faire ça avant d'avoir mis à jour q et masse
1155  ! write(*,*)'vlsplt 942: iq,nqChildren(iq)=',iq,tracers(iq)%nqChildren
1156  do ifils=1,tracers(iq)%nqDescen
1157    iq2=tracers(iq)%iqDescen(ifils)
1158!$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
1159    DO l=1,llm
1160      DO ij=ijb,ije
1161       ! !MVals: veiller a ce qu'on n'ait pas de denominateur nul
1162        masse(ij,l,iq2)=max(masse(ij,l,iq)*q(ij,l,iq),min_qMass)
1163        if (q(ij,l,iq).gt.min_qParent) then
1164          Ratio(ij,l,iq2)=q(ij,l,iq2)/q(ij,l,iq)
1165        else
1166          Ratio(ij,l,iq2)=min_ratio
1167        endif
1168        ! !wq(ij,l,iq2)=wq(ij,l,iq) ! correction bug le 15mai2015
1169        w(ij,l,iq2)=wq(ij,l,iq)
[4050]1170      enddo
[5248]1171    enddo
1172!$OMP END DO NOWAIT
1173  enddo
1174!$OMP BARRIER
[2270]1175
[5248]1176  do ifils=1,tracers(iq)%nqChildren
1177    iq2=tracers(iq)%iqDescen(ifils)
1178    call vlz_loc(Ratio,pente_max,masse,w,ijb_x,ije_x,iq2)
1179  enddo
1180  ! end CRisi
[2281]1181
[5248]1182  ! CRisi: On rajoute ici une barrière car on veut être sur que tous les
1183  ! wq soient synchronisés
[1632]1184
[5248]1185!$OMP BARRIER
1186!$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
1187  DO l=1,llm
1188     DO ij=ijb,ije
1189        newmasse=masse(ij,l,iq)+w(ij,l+1,iq)-w(ij,l,iq)
1190        q(ij,l,iq)=(q(ij,l,iq)*masse(ij,l,iq) &
1191              +wq(ij,l+1,iq)-wq(ij,l,iq)) &
1192              /newmasse
1193        masse(ij,l,iq)=newmasse
1194     ENDDO
1195  ENDDO
1196!$OMP END DO NOWAIT
1197
1198
1199  ! retablir les fils en rapport de melange par rapport a l'air:
1200  do ifils=1,tracers(iq)%nqDescen
1201    iq2=tracers(iq)%iqDescen(ifils)
1202!$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
1203    DO l=1,llm
1204      DO ij=ijb,ije
1205        q(ij,l,iq2)=q(ij,l,iq)*Ratio(ij,l,iq2)
[4050]1206      enddo
[5248]1207    enddo
1208!$OMP END DO NOWAIT
1209  enddo
[1632]1210
[5248]1211  RETURN
1212END SUBROUTINE vlz_loc
1213 ! SUBROUTINE minmaxq(zq,qmin,qmax,comment)
1214!
[5271]1215!  INCLUDE "dimensions_mod.f90"
[5248]1216!  INCLUDE "paramet.h"
[1632]1217
[5248]1218!  CHARACTER*(*) comment
1219!  real qmin,qmax
1220!  real zq(ip1jmp1,llm)
[1632]1221
[5248]1222!  INTEGER jadrs(ip1jmp1), jbad, k, i
[1632]1223
1224
[5248]1225!  DO k = 1, llm
1226!     jbad = 0
1227!     DO i = 1, ip1jmp1
1228!     IF (zq(i,k).GT.qmax .OR. zq(i,k).LT.qmin) THEN
1229!        jbad = jbad + 1
1230!        jadrs(jbad) = i
1231!     ENDIF
1232!     ENDDO
1233!     IF (jbad.GT.0) THEN
1234!     PRINT*, comment
1235!     DO i = 1, jbad
1236!c            PRINT*, "i,k,zq=", jadrs(i),k,zq(jadrs(i),k)
1237!     ENDDO
1238!     ENDIF
1239!  ENDDO
[1632]1240
[5248]1241!  return
1242!  end
[1632]1243
1244
1245
1246
Note: See TracBrowser for help on using the repository browser.