source: LMDZ6/trunk/libf/dyn3dmem/vlspltqs_loc.F90 @ 5281

Last change on this file since 5281 was 5281, checked in by abarral, 8 hours ago

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