source: LMDZ6/branches/Amaury_dev/libf/dyn3d/vlspltqs.F90 @ 5112

Last change on this file since 5112 was 5106, checked in by abarral, 4 months ago

Turn coefils.h into lmdz_coefils.f90
Put filtreg.F90 inside lmdz_filtreg.F90
Turn mod_filtreg_p.F90 into lmdz_filtreg_p.F90
Delete obsolete parafilt.h*
(lint) remove spaces between routine name and args

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