source: LMDZ6/branches/Amaury_dev/libf/dyn3dmem/vlspltqs_loc.f90 @ 5136

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

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