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

Last change on this file since 5272 was 5272, checked in by abarral, 3 months ago

Turn paramet.h into a module

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