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

Last change on this file since 5208 was 5182, checked in by abarral, 11 days ago

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