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

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