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

Last change on this file since 5136 was 5136, checked in by abarral, 4 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
RevLine 
[5105]1! $Id: vlspltqs_loc.f90 5136 2024-07-28 14:17:54Z abarral $
[5099]2
[5118]3SUBROUTINE vlxqs_loc(q, pente_max, masse, u_m, qsat, ijb_x, ije_x, iq)
[5105]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
[5118]13  USE infotrac, ONLY: nqtot, tracers, & ! CRisi                 &
14          min_qParent, min_qMass, min_ratio ! MVals et CRisi7
[5105]15  IMPLICIT NONE
16  !
[5134]17  INCLUDE "dimensions.h"
18  INCLUDE "paramet.h"
[5105]19  !
20  !
21  !   Arguments:
22  !   ----------
[5118]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)
[5105]27  INTEGER :: iq ! CRisi
28  !
29  !  Local
30  !   ---------
31  !
[5118]32  INTEGER :: ij, l, j, i, iju, ijq, indu(ijnb_u), niju
33  INTEGER :: n0, iadvplus(ijb_u:ije_u, llm), nl(llm)
[5105]34  !
[5118]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)
[5105]37  REAL :: zz(ijb_u:ije_u)
[5118]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
[1632]42
[5118]43  INTEGER :: ijb, ije, ijb_x, ije_x
[1632]44
[5116]45  !WRITE(*,*) 'vlspltqs 58: entree vlxqs_loc, iq,ijb_x=',
[5105]46  ! &   iq,ijb_x
[1632]47
[5105]48  !   calcul de la pente a droite et a gauche de la maille
[1632]49
[5105]50  !  ijb=ij_begin
51  !  ije=ij_end
[1632]52
[5118]53  ijb = ijb_x
54  ije = ije_x
[1632]55
[5118]56  IF (pole_nord.AND.ijb==1) ijb = ijb + iip1
57  IF (pole_sud.AND.ije==ip1jmp1)  ije = ije - iip1
[1632]58
[5105]59  IF (pente_max>-1.e-5) THEN
[5118]60    ! IF (pente_max.gt.10) THEN
[1632]61
[5118]62    !   calcul des pentes avec limitation, Van Leer scheme I:
63    !   -----------------------------------------------------
[1632]64
[5118]65    !   calcul de la pente aux points u
[1632]66
[5118]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
[1632]76
[5118]77      DO ij = ijb, ije
78        adxqu(ij) = abs(dxqu(ij))
79      ENDDO
[5098]80
[5118]81      !   calcul de la pente maximum dans la maille en valeur absolue
[1632]82
[5118]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)))
[1632]88
[5118]89      ENDDO
[1632]90
[5118]91      DO ij = ijb + iip1 - 1, ije, iip1
92        dxqmax(ij - iim, l) = dxqmax(ij, l)
93      ENDDO
[1632]94
[5118]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
[1632]106
[5118]107    ENDDO ! l=1,llm
108    !$OMP END DO NOWAIT
[1632]109
[5105]110  ELSE ! (pente_max.lt.-1.e-5)
[1632]111
[5118]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
[1632]122
[5118]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
[1632]133
[5118]134    ENDDO
135    !$OMP END DO NOWAIT
[5105]136  ENDIF ! (pente_max.lt.-1.e-5)
[1632]137
[5105]138  !   bouclage de la pente en iip1:
139  !   -----------------------------
[5118]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
[1632]145
[5118]146    DO ij = ijb, ije
147      iadvplus(ij, l) = 0
148    ENDDO
[1632]149
[5105]150  ENDDO
[5118]151  !$OMP END DO NOWAIT
[1632]152
[5117]153  IF (pole_nord) THEN
[5118]154    !$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
155    DO l = 1, llm
156      iadvplus(1:iip1, l) = 0
[5105]157    ENDDO
[5118]158    !$OMP END DO NOWAIT
[5117]159  ENDIF
[1632]160
[5117]161  IF (pole_sud)  THEN
[5118]162    !$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
163    DO l = 1, llm
164      iadvplus(ip1jm + 1:ip1jmp1, l) = 0
[5105]165    ENDDO
[5118]166    !$OMP END DO NOWAIT
[5117]167  ENDIF
[1632]168
[5105]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)
[5118]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))
[5105]180      ELSE
[5118]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))
[5105]184      ENDIF
[5118]185    ENDDO
[5105]186  ENDDO
[5118]187  !$OMP END DO NOWAIT
[1632]188
189
[5105]190  !   detection des points ou on advecte plus que la masse de la
191  !   maille
[5118]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
[5105]200  ENDDO
[5118]201  !$OMP END DO NOWAIT
[1632]202
[5118]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
[5105]208  ENDDO
[5118]209  !$OMP END DO NOWAIT
[1632]210
211
212
[5105]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.
[1632]216
[5105]217  !   pas d'influence de la pression saturante (pour l'instant)
[2270]218
[5105]219  !  calcul du nombre de maille sur lequel on advecte plus que la maille.
220
[5118]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)
[5105]229  ENDDO
[5118]230  !$OMP END DO NOWAIT
[5105]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
[5118]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)
[5105]250
[5118]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))
[5105]285        ENDIF
[5118]286      ENDDO
287    ENDIF
288  ENDDO
289  !$OMP END DO NOWAIT
[5105]290  !ym      ENDIF  ! n0.gt.0
291
292
293
294  !   bouclage en latitude
[5118]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)
[5105]299    ENDDO
300  ENDDO
[5118]301  !$OMP END DO NOWAIT
[5105]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
[5116]305  !WRITE(*,*) 'vlspltqs 336: iq,ijb_x,nqChildren(iq)=',
[5105]306  ! &     iq,ijb_x,tracers(iq)%nqChildren
307
[5118]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
[5113]313        !MVals: veiller a ce qu'on n'ait pas de denominateur nul
[5118]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)
[5105]317        else
[5118]318          Ratio(ij, l, iq2) = min_ratio
[5105]319        endif
[4050]320      enddo
[5105]321    enddo
[5118]322    !$OMP END DO NOWAIT
[5105]323  enddo
[5118]324  do ifils = 1, tracers(iq)%nqChildren
325    iq2 = tracers(iq)%iqDescen(ifils)
[5116]326    !WRITE(*,*) 'vlxqs 349: on appelle vlx pour iq2=',iq2
[5118]327    CALL vlx_loc(Ratio, pente_max, masse, u_mq, ijb_x, ije_x, iq2)
[5105]328  enddo
329  ! end CRisi
[2270]330
[5116]331  !WRITE(*,*) 'vlspltqs 360: iq,ijb_x=',iq,ijb_x
[2270]332
[5105]333  !   calcul des tendances
[5118]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
[5105]349  ENDDO
[5118]350  !$OMP END DO NOWAIT
[2270]351
[5116]352  !WRITE(*,*) 'vlspltqs 380: iq,ijb_x=',iq,ijb_x
[2270]353
[5105]354  ! retablir les fils en rapport de melange par rapport a l'air:
[5118]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)
[4050]361      enddo
[5118]362      DO ij = ijb + iip1 - 1, ije, iip1
363        q(ij - iim, l, iq2) = q(ij, l, iq2)
[5105]364      enddo ! DO ij=ijb+iip1-1,ije,iip1
365    enddo
[5118]366    !$OMP END DO NOWAIT
[5105]367  enddo
[2270]368
[5116]369  !WRITE(*,*) 'vlspltqs 399: iq,ijb_x=',iq,ijb_x
[2270]370
[5105]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)
[1632]373
[5105]374END SUBROUTINE vlxqs_loc
[5118]375SUBROUTINE vlyqs_loc(q, pente_max, masse, masse_adv_v, qsat, iq)
[5105]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
[5118]388  USE infotrac, ONLY: nqtot, tracers, & ! CRisi                 &
389          min_qParent, min_qMass, min_ratio ! MVals et CRisi
[5105]390  USE comconst_mod, ONLY: pi
[5118]391  USE lmdz_iniprint, ONLY: lunout, prt_level
[5123]392  USE lmdz_ssum_scopy, ONLY: ssum
[5136]393  USE lmdz_comgeom
[5123]394
[5105]395  IMPLICIT NONE
396  !
[5134]397  INCLUDE "dimensions.h"
398  INCLUDE "paramet.h"
[5105]399  !
400  !
401  !   Arguments:
402  !   ----------
[5118]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)
[5105]407  INTEGER :: iq ! CRisi
408  !
409  !  Local
410  !   ---------
411  !
[5118]412  INTEGER :: i, ij, l
[5105]413  !
[5118]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)
[2270]418
[5118]419  REAL :: qpns, qpsn, dyn1, dys1, dyn2, dys2, newmasse, fn, fs
[5105]420  ! REAL newq,oldmasse
421  Logical :: first
422  SAVE first
[5118]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)
[5105]431  !
432  !
[5118]433  REAL :: Ratio(ijb_u:ije_u, llm, nqtot) ! CRisi
434  INTEGER :: ifils, iq2 ! CRisi
[1632]435
[5105]436  DATA first/.TRUE./
[5118]437  INTEGER :: ijb, ije
438  INTEGER :: ijbm, ijem
[5098]439
[5118]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
[5117]446  IF ((ij>=ijb).AND.(ij<=ije)) THEN
[5116]447    !WRITE(*,*) 'vlyqs 480: ij,l,iq,ijb,q(ij,l,:)=',
[5118]448    ! &             ij,l,iq,ijb,q(ij,l,:)
[5117]449  ENDIF
[1632]450
[5105]451  IF(first) THEN
[5118]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)
[5105]467  ENDIF
[1632]468
[5105]469  !
[1632]470
[5118]471  !$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
[5105]472  DO l = 1, llm
[5118]473    !
474    !   --------------------------------
475    !  CALCUL EN LATITUDE
476    !   --------------------------------
[1632]477
[5118]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.
[1632]481
[5118]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
[1632]488
[5118]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
[1632]495
496
[5118]497    !   calcul des pentes aux points v
[1632]498
[5118]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
[1632]503
[5118]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
[1632]508
509
[5118]510    !   calcul des pentes aux points scalaires
[1632]511
[5118]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
[1632]516
[5118]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
[1632]522
[5118]523    IF (pole_nord) THEN
[1632]524
[5118]525      !   calcul des pentes aux poles
526      DO ij = 1, iip1
527        dyq(ij, l) = qpns - q(ij + iip1, l, iq)
528      ENDDO
[1632]529
[5118]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
[5105]540
[5118]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
[1632]548
[5118]549      DO ij = 1, iip1
550        dyq(ij, l) = fn * dyq(ij, l)
551      ENDDO
[1632]552
[5118]553    ENDIF
[1632]554
[5118]555    IF (pole_sud) THEN
[1632]556
[5118]557      DO ij = 1, iip1
558        dyq(ip1jm + ij, l) = q(ip1jm + ij - iip1, l, iq) - qpsn
559      ENDDO
[5105]560
[5118]561      dys1 = 0.
562      dys2 = 0.
[5105]563
[5118]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
[5105]568
[5118]569      DO ij = 1, iip1
570        dyq(ip1jm + ij, l) = dys1 * sinlon(ij) + dys2 * coslon(ij)
571      ENDDO
[5105]572
[5118]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
[5105]580
[5118]581      DO ij = 1, iip1
582        dyq(ip1jm + ij, l) = fs * dyq(ip1jm + ij, l)
583      ENDDO
[5105]584
[5118]585    ENDIF
[5105]586
587
[5118]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
[5105]654
[5118]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
[5105]660
[5118]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
[5105]668
669  ENDDO
[5118]670  !$OMP END DO NOWAIT
[5105]671
[5118]672  ijb = ij_begin - iip1
673  ije = ij_end
674  IF (pole_nord) ijb = ij_begin
675  IF (pole_sud)  ije = ij_end - iip1
[5105]676
[5118]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
[5105]690  ENDDO
[5118]691  !$OMP END DO NOWAIT
[5105]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
[5116]695  ! WRITE(*,*)'vlyqs 689: iq,nqChildren(iq)=',iq,
[5105]696  !    &             tracers(iq)%nqChildren
697
[5118]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
[5105]706
[5116]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
[5118]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
[5113]714      ! modif des bornes: CRisi 16 nov 2020
715      ! d'abord masse avec bornes corrigees
[5118]716      DO ij = ijbm, ijem
[5113]717        !MVals: veiller a ce qu'on n'ait pas de denominateur nul
[5118]718        masse(ij, l, iq2) = max(masse(ij, l, iq) * q(ij, l, iq), min_qMass)
[5105]719      enddo !DO ij=ijbm,ijem
720
[5113]721      ! ensuite Ratio avec anciennes bornes
[5118]722      DO ij = ijb, ije
[5113]723        !MVals: veiller a ce qu'on n'ait pas de denominateur nul
[5116]724        !WRITE(lunout,*) 'ij,l,q(ij,l,iq)=',ij,l,q(ij,l,iq)
[5118]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)
[5105]727        else
[5118]728          Ratio(ij, l, iq2) = min_ratio
[5105]729        endif
730      enddo !DO ij=ijbm,ijem
731    enddo !DO l=1,llm
[5118]732    !$OMP END DO NOWAIT
[5105]733  enddo
[5118]734  do ifils = 1, tracers(iq)%nqChildren
735    iq2 = tracers(iq)%iqDescen(ifils)
[5116]736    !WRITE(lunout,*) 'vly: appel recursiv vly iq2=',iq2
[5118]737    CALL vly_loc(Ratio, pente_max, masse, qbyv, iq2)
[5105]738  enddo
[1632]739
740
[5105]741  ! end CRisi
[1632]742
[5118]743  ijb = ij_begin
744  ije = ij_end
745  IF (pole_nord) ijb = ij_begin + iip1
746  IF (pole_sud)  ije = ij_end - iip1
[1632]747
[5118]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
[2270]758
[5118]759    IF (pole_nord) THEN
[3800]760
[5118]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)) / &
[5105]766                newmasse
[5118]767        masse(ij, l, iq) = newmasse
768      ENDDO
[2270]769
[5118]770    ENDIF
[2270]771
[5118]772    IF (pole_sud) THEN
[5128]773      convps = -SSUM(iim, qbyv(ip1jm - iim, l, iq), 1) / apols
[5118]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)) / &
[5105]778                newmasse
[5118]779        masse(ij, l, iq) = newmasse
780      ENDDO
781    ENDIF
782    !.-. fin ancienne version
[1632]783
[5118]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
[5105]806  ENDDO
[5118]807  !$OMP END DO NOWAIT
[1632]808
[5105]809  ! retablir les fils en rapport de melange par rapport a l'air:
[5118]810  ijb = ij_begin
811  ije = ij_end
812  ! if (pole_nord) ijb=ij_begin+iip1
813  ! if (pole_sud)  ije=ij_end-iip1
[2270]814
[5118]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)
[4050]821      enddo
[5105]822    enddo
[5118]823    !$OMP END DO NOWAIT
[5105]824  enddo
[2270]825
[5105]826END SUBROUTINE vlyqs_loc
Note: See TracBrowser for help on using the repository browser.