source: LMDZ6/branches/Amaury_dev/libf/dyn3d_common/advn.f90 @ 5209

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

Put dimensions.h and paramet.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:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 25.0 KB
RevLine 
[524]1! $Header$
[5099]2
[5118]3SUBROUTINE advn(q, masse, w, pbaru, pbarv, pdt, mode)
[5159]4
[5105]5  ! Auteur : F. Hourdin
[5159]6
[5105]7  !    ********************************************************************
8  ! Shema  d'advection " pseudo amont " .
9  !    ********************************************************************
10  ! q,pbaru,pbarv,w sont des arguments d'entree  pour le s-pg ....
[5159]11
[5105]12  !   pbaru,pbarv,w flux de masse en u ,v ,w
13  !   pdt pas de temps
[5159]14
[5105]15  !   --------------------------------------------------------------------
[5118]16  USE lmdz_iniprint, ONLY: lunout, prt_level
[5123]17  USE lmdz_ssum_scopy, ONLY: ssum
[5136]18  USE lmdz_comgeom
[5123]19
[5159]20USE lmdz_dimensions, ONLY: iim, jjm, llm, ndm
21  USE lmdz_paramet
[5105]22  IMPLICIT NONE
23  !
[524]24
[5159]25
26
27
[5105]28  !   Arguments:
29  !   ----------
[5116]30  INTEGER :: mode
[5118]31  REAL :: masse(ip1jmp1, llm)
32  REAL :: pbaru(ip1jmp1, llm), pbarv(ip1jm, llm)
33  REAL :: q(ip1jmp1, llm)
34  REAL :: w(ip1jmp1, llm), pdt
[5159]35
[5105]36  !  Local
37  !   ---------
[5159]38
[5118]39  INTEGER :: i, ij, l, j, ii
40  INTEGER :: ijlqmin, iqmin, jqmin, lqmin
[5116]41  INTEGER :: ismin
[5159]42
[5118]43  REAL :: zm(ip1jmp1, llm), newmasse
44  REAL :: mu(ip1jmp1, llm)
45  REAL :: mv(ip1jm, llm)
46  REAL :: mw(ip1jmp1, llm + 1)
47  REAL :: zq(ip1jmp1, llm), zz, qpn, qps
48  REAL :: zqg(ip1jmp1, llm), zqd(ip1jmp1, llm)
49  REAL :: zqs(ip1jmp1, llm), zqn(ip1jmp1, llm)
50  REAL :: zqh(ip1jmp1, llm), zqb(ip1jmp1, llm)
51  REAL :: temps0, temps1, temps2, temps3
[5123]52  REAL :: ztemps1, ztemps2
[5118]53  save temps1, temps2, temps3
54  REAL :: zzpbar, zzw
[524]55
[5118]56  REAL :: qmin, qmax
57  data qmin, qmax/0., 1./
58  data temps1, temps2, temps3/0., 0., 0./
[524]59
[5105]60  zzpbar = 0.5 * pdt
[5118]61  zzw = pdt
[524]62
[5118]63  DO l = 1, llm
64    DO ij = iip2, ip1jm
65      mu(ij, l) = pbaru(ij, l) * zzpbar
66    ENDDO
67    DO ij = 1, ip1jm
68      mv(ij, l) = pbarv(ij, l) * zzpbar
69    ENDDO
70    DO ij = 1, ip1jmp1
71      mw(ij, l) = w(ij, l) * zzw
72    ENDDO
[5105]73  ENDDO
[524]74
[5118]75  DO ij = 1, ip1jmp1
76    mw(ij, llm + 1) = 0.
[5105]77  ENDDO
[524]78
[5158]79  DO l = 1, llm
[5118]80    qpn = 0.
81    qps = 0.
[5158]82    DO ij = 1, iim
[5118]83      qpn = qpn + q(ij, l) * masse(ij, l)
84      qps = qps + q(ip1jm + ij, l) * masse(ip1jm + ij, l)
85    enddo
86    qpn = qpn / ssum(iim, masse(1, l), 1)
87    qps = qps / ssum(iim, masse(ip1jm + 1, l), 1)
[5158]88    DO ij = 1, iip1
[5118]89      q(ij, l) = qpn
90      q(ip1jm + ij, l) = qps
91    enddo
[5105]92  enddo
[524]93
[5158]94  DO ij = 1, ip1jmp1
[5118]95    mw(ij, llm + 1) = 0.
[5105]96  enddo
[5158]97  DO l = 1, llm
98    DO ij = 1, ip1jmp1
[5118]99      zq(ij, l) = q(ij, l)
100      zm(ij, l) = masse(ij, l)
101    enddo
[5105]102  enddo
[524]103
[5105]104  ! CALL minmaxq(zq,qmin,qmax,'avant vlx     ')
[5118]105  CALL advnqx(zq, zqg, zqd)
106  CALL advnx(zq, zqg, zqd, zm, mu, mode)
107  CALL advnqy(zq, zqs, zqn)
108  CALL advny(zq, zqs, zqn, zm, mv)
109  CALL advnqz(zq, zqh, zqb)
110  CALL advnz(zq, zqh, zqb, zm, mw)
[5105]111  ! CALL vlz(zq,0.,zm,mw)
[5118]112  CALL advnqy(zq, zqs, zqn)
113  CALL advny(zq, zqs, zqn, zm, mv)
114  CALL advnqx(zq, zqg, zqd)
115  CALL advnx(zq, zqg, zqd, zm, mu, mode)
[5105]116  ! CALL minmaxq(zq,qmin,qmax,'apres vlx     ')
[524]117
[5158]118  DO l = 1, llm
119    DO ij = 1, ip1jmp1
[5118]120      q(ij, l) = zq(ij, l)
121    enddo
[5158]122    DO ij = 1, ip1jm + 1, iip1
[5118]123      q(ij + iim, l) = q(ij, l)
124    enddo
[5105]125  enddo
[524]126
[5105]127  RETURN
128END SUBROUTINE advn
[524]129
[5118]130SUBROUTINE advnqx(q, qg, qd)
[5159]131
[5105]132  ! Auteurs:   Calcul des valeurs de q aux point u.
[5159]133
[5105]134  !   --------------------------------------------------------------------
[5118]135  USE lmdz_iniprint, ONLY: lunout, prt_level
[5159]136USE lmdz_dimensions, ONLY: iim, jjm, llm, ndm
137  USE lmdz_paramet
[5105]138  IMPLICIT NONE
139  !
[5159]140
141
142
143
[5105]144  !   Arguments:
145  !   ----------
[5118]146  REAL :: q(ip1jmp1, llm), qg(ip1jmp1, llm), qd(ip1jmp1, llm)
[5159]147
[5105]148  !  Local
149  !   ---------
[5159]150
[5118]151  INTEGER :: ij, l
[5159]152
[5118]153  REAL :: dxqu(ip1jmp1), zqu(ip1jmp1)
154  REAL :: zqmax(ip1jmp1), zqmin(ip1jmp1)
[5117]155  LOGICAL :: extremum(ip1jmp1)
[524]156
[5116]157  INTEGER :: mode
[5105]158  save mode
159  data mode/1/
[524]160
[5105]161  !   calcul des pentes en u:
162  !   -----------------------
[5117]163  IF (mode==0) THEN
[5158]164    DO l = 1, llm
165      DO ij = 1, ip1jm
[5118]166        qd(ij, l) = q(ij, l)
167        qg(ij, l) = q(ij, l)
168      enddo
169    enddo
[5105]170  else
[5158]171    DO l = 1, llm
172      DO ij = iip2, ip1jm - 1
[5118]173        dxqu(ij) = q(ij + 1, l) - q(ij, l)
174        zqu(ij) = 0.5 * (q(ij + 1, l) + q(ij, l))
175      enddo
[5158]176      DO ij = iip1 + iip1, ip1jm, iip1
[5118]177        dxqu(ij) = dxqu(ij - iim)
178        zqu(ij) = zqu(ij - iim)
179      enddo
[5158]180      DO ij = iip2, ip1jm - 1
[5118]181        zqu(ij) = zqu(ij) - dxqu(ij + 1) / 12.
182      enddo
[5158]183      DO ij = iip1 + iip1, ip1jm, iip1
[5118]184        zqu(ij) = zqu(ij - iim)
185      enddo
[5158]186      DO ij = iip2 + 1, ip1jm
[5118]187        zqu(ij) = zqu(ij) + dxqu(ij - 1) / 12.
188      enddo
[5158]189      DO ij = iip1 + iip1, ip1jm, iip1
[5118]190        zqu(ij - iim) = zqu(ij)
191      enddo
[524]192
[5118]193      !   calcul des valeurs max et min acceptees aux interfaces
[524]194
[5158]195      DO ij = iip2, ip1jm - 1
[5118]196        zqmax(ij) = max(q(ij + 1, l), q(ij, l))
197        zqmin(ij) = min(q(ij + 1, l), q(ij, l))
198      enddo
[5158]199      DO ij = iip1 + iip1, ip1jm, iip1
[5118]200        zqmax(ij) = zqmax(ij - iim)
201        zqmin(ij) = zqmin(ij - iim)
202      enddo
[5158]203      DO ij = iip2 + 1, ip1jm
[5118]204        extremum(ij) = dxqu(ij) * dxqu(ij - 1)<=0.
205      enddo
[5158]206      DO ij = iip1 + iip1, ip1jm, iip1
[5118]207        extremum(ij - iim) = extremum(ij)
208      enddo
[5158]209      DO ij = iip2, ip1jm
[5118]210        zqu(ij) = min(max(zqmin(ij), zqu(ij)), zqmax(ij))
211      enddo
[5158]212      DO ij = iip2 + 1, ip1jm
[5116]213        IF(extremum(ij)) THEN
[5118]214          qg(ij, l) = q(ij, l)
215          qd(ij, l) = q(ij, l)
[5105]216        else
[5118]217          qd(ij, l) = zqu(ij)
218          qg(ij, l) = zqu(ij - 1)
[5105]219        endif
[5118]220      enddo
[5158]221      DO ij = iip1 + iip1, ip1jm, iip1
[5118]222        qd(ij - iim, l) = qd(ij, l)
223        qg(ij - iim, l) = qg(ij, l)
224      enddo
[524]225
[5118]226      goto 8888
[524]227
[5158]228      DO ij = iip2 + 1, ip1jm
[5118]229        IF(extremum(ij).and..not.extremum(ij - 1)) &
230                qd(ij - 1, l) = q(ij, l)
231      enddo
[524]232
[5158]233      DO ij = iip1 + iip1, ip1jm, iip1
[5118]234        qd(ij - iim, l) = qd(ij, l)
235      enddo
[5158]236      DO ij = iip2, ip1jm - 1
[5118]237        IF (extremum(ij).and..not.extremum(ij + 1)) &
238                qg(ij + 1, l) = q(ij, l)
239      enddo
[524]240
[5158]241      DO ij = iip1 + iip1, ip1jm, iip1
[5118]242        qg(ij, l) = qg(ij - iim, l)
243      enddo
244      8888   continue
245    enddo
[5117]246  ENDIF
[5105]247  RETURN
248END SUBROUTINE advnqx
[5118]249SUBROUTINE advnqy(q, qs, qn)
[5159]250
[5105]251  ! Auteurs:   Calcul des valeurs de q aux point v.
[5159]252
[5105]253  !   --------------------------------------------------------------------
[5118]254  USE lmdz_iniprint, ONLY: lunout, prt_level
[5159]255USE lmdz_dimensions, ONLY: iim, jjm, llm, ndm
256  USE lmdz_paramet
[5105]257  IMPLICIT NONE
258  !
[5159]259
260
261
262
[5105]263  !   Arguments:
264  !   ----------
[5118]265  REAL :: q(ip1jmp1, llm), qs(ip1jmp1, llm), qn(ip1jmp1, llm)
[5159]266
[5105]267  !  Local
268  !   ---------
[5159]269
[5118]270  INTEGER :: ij, l
[5159]271
[5118]272  REAL :: dyqv(ip1jm), zqv(ip1jm, llm)
273  REAL :: zqmax(ip1jm), zqmin(ip1jm)
[5117]274  LOGICAL :: extremum(ip1jmp1)
[524]275
[5116]276  INTEGER :: mode
[5105]277  save mode
278  data mode/1/
[524]279
[5117]280  IF (mode==0) THEN
[5158]281    DO l = 1, llm
282      DO ij = 1, ip1jmp1
[5118]283        qn(ij, l) = q(ij, l)
284        qs(ij, l) = q(ij, l)
285      enddo
286    enddo
[5105]287  else
[524]288
[5118]289    !   calcul des pentes en u:
290    !   -----------------------
[5158]291    DO l = 1, llm
292      DO ij = 1, ip1jm
[5118]293        dyqv(ij) = q(ij, l) - q(ij + iip1, l)
294      enddo
[524]295
[5158]296      DO ij = iip2, ip1jm - iip1
[5118]297        zqv(ij, l) = 0.5 * (q(ij + iip1, l) + q(ij, l))
298        zqv(ij, l) = zqv(ij, l) + (dyqv(ij + iip1) - dyqv(ij - iip1)) / 12.
299      enddo
[524]300
[5158]301      DO ij = iip2, ip1jm
[5118]302        extremum(ij) = dyqv(ij) * dyqv(ij - iip1)<=0.
303      enddo
[524]304
[5118]305      ! Pas de pentes aux poles
[5158]306      DO ij = 1, iip1
[5118]307        zqv(ij, l) = q(ij, l)
308        zqv(ip1jm - iip1 + ij, l) = q(ip1jm + ij, l)
309        extremum(ij) = .TRUE.
310        extremum(ip1jmp1 - iip1 + ij) = .TRUE.
311      enddo
[524]312
[5118]313      !   calcul des valeurs max et min acceptees aux interfaces
[5158]314      DO ij = 1, ip1jm
[5118]315        zqmax(ij) = max(q(ij + iip1, l), q(ij, l))
316        zqmin(ij) = min(q(ij + iip1, l), q(ij, l))
317      enddo
[524]318
[5158]319      DO ij = 1, ip1jm
[5118]320        zqv(ij, l) = min(max(zqmin(ij), zqv(ij, l)), zqmax(ij))
321      enddo
[524]322
[5158]323      DO ij = iip2, ip1jm
[5116]324        IF(extremum(ij)) THEN
[5118]325          qs(ij, l) = q(ij, l)
326          qn(ij, l) = q(ij, l)
327          ! if (.NOT.extremum(ij-iip1)) qs(ij-iip1,l)=q(ij,l)
328          ! if (.NOT.extremum(ij+iip1)) qn(ij+iip1,l)=q(ij,l)
[5105]329        else
[5118]330          qs(ij, l) = zqv(ij, l)
331          qn(ij, l) = zqv(ij - iip1, l)
[5105]332        endif
[5118]333      enddo
[524]334
[5158]335      DO ij = 1, iip1
[5118]336        qs(ij, l) = q(ij, l)
337        qn(ij, l) = q(ij, l)
338        qs(ip1jm + ij, l) = q(ip1jm + ij, l)
339        qn(ip1jm + ij, l) = q(ip1jm + ij, l)
340      enddo
[524]341
[5118]342    enddo
[5117]343  ENDIF
[5105]344  RETURN
345END SUBROUTINE advnqy
[524]346
[5118]347SUBROUTINE advnqz(q, qh, qb)
[5159]348
[5105]349  ! Auteurs:   Calcul des valeurs de q aux point v.
[5159]350
[5105]351  !   --------------------------------------------------------------------
[5118]352  USE lmdz_iniprint, ONLY: lunout, prt_level
[5159]353USE lmdz_dimensions, ONLY: iim, jjm, llm, ndm
354  USE lmdz_paramet
[5105]355  IMPLICIT NONE
356  !
[5159]357
358
359
360
[5105]361  !   Arguments:
362  !   ----------
[5118]363  REAL :: q(ip1jmp1, llm), qh(ip1jmp1, llm), qb(ip1jmp1, llm)
[5159]364
[5105]365  !  Local
366  !   ---------
[5159]367
[5118]368  INTEGER :: ij, l
[5159]369
[5118]370  REAL :: dzqw(ip1jmp1, llm + 1), zqw(ip1jmp1, llm + 1)
371  REAL :: zqmax(ip1jmp1, llm), zqmin(ip1jmp1, llm)
372  LOGICAL :: extremum(ip1jmp1, llm)
[524]373
[5116]374  INTEGER :: mode
[5105]375  save mode
[524]376
[5105]377  data mode/1/
[524]378
[5105]379  !   calcul des pentes en u:
380  !   -----------------------
[524]381
[5117]382  IF (mode==0) THEN
[5158]383    DO l = 1, llm
384      DO ij = 1, ip1jmp1
[5118]385        qb(ij, l) = q(ij, l)
386        qh(ij, l) = q(ij, l)
387      enddo
388    enddo
[5105]389  else
[5158]390    DO l = 2, llm
391      DO ij = 1, ip1jmp1
[5118]392        dzqw(ij, l) = q(ij, l - 1) - q(ij, l)
393        zqw(ij, l) = 0.5 * (q(ij, l - 1) + q(ij, l))
394      enddo
395    enddo
[5158]396    DO ij = 1, ip1jmp1
[5118]397      dzqw(ij, 1) = 0.
398      dzqw(ij, llm + 1) = 0.
399    enddo
[5158]400    DO l = 2, llm
401      DO ij = 1, ip1jmp1
[5118]402        zqw(ij, l) = zqw(ij, l) + (dzqw(ij, l + 1) - dzqw(ij, l - 1)) / 12.
403      enddo
404    enddo
[5158]405    DO l = 2, llm - 1
406      DO ij = 1, ip1jmp1
[5118]407        extremum(ij, l) = dzqw(ij, l) * dzqw(ij, l + 1)<=0.
408      enddo
409    enddo
[524]410
[5118]411    ! Pas de pentes en bas et en haut
[5158]412    DO ij = 1, ip1jmp1
[5118]413      zqw(ij, 2) = q(ij, 1)
414      zqw(ij, llm) = q(ij, llm)
415      extremum(ij, 1) = .TRUE.
416      extremum(ij, llm) = .TRUE.
417    enddo
[524]418
[5118]419    !   calcul des valeurs max et min acceptees aux interfaces
[5158]420    DO l = 2, llm
421      DO ij = 1, ip1jmp1
[5118]422        zqmax(ij, l) = max(q(ij, l - 1), q(ij, l))
423        zqmin(ij, l) = min(q(ij, l - 1), q(ij, l))
424      enddo
425    enddo
[524]426
[5158]427    DO l = 2, llm
428      DO ij = 1, ip1jmp1
[5118]429        zqw(ij, l) = min(max(zqmin(ij, l), zqw(ij, l)), zqmax(ij, l))
430      enddo
431    enddo
[524]432
[5158]433    DO l = 2, llm - 1
434      DO ij = 1, ip1jmp1
[5118]435        IF(extremum(ij, l)) THEN
436          qh(ij, l) = q(ij, l)
437          qb(ij, l) = q(ij, l)
[5105]438        else
[5118]439          qh(ij, l) = zqw(ij, l + 1)
440          qb(ij, l) = zqw(ij, l)
[5105]441        endif
[5118]442      enddo
443    enddo
444    ! do l=2,llm-1
445    !    do ij=1,ip1jmp1
446    !       IF(extremum(ij,l)) THEN
447    !          if (.NOT.extremum(ij,l-1)) qh(ij,l-1)=q(ij,l)
448    !          if (.NOT.extremum(ij,l+1)) qb(ij,l+1)=q(ij,l)
449    !       endif
450    !    enddo
451    ! enddo
[524]452
[5158]453    DO ij = 1, ip1jmp1
[5118]454      qb(ij, 1) = q(ij, 1)
455      qh(ij, 1) = q(ij, 1)
456      qb(ij, llm) = q(ij, llm)
457      qh(ij, llm) = q(ij, llm)
458    enddo
[524]459
[5117]460  ENDIF
[524]461
[5105]462  RETURN
463END SUBROUTINE advnqz
[524]464
[5118]465SUBROUTINE advnx(q, qg, qd, masse, u_m, mode)
[5159]466
[5105]467  ! Auteur : F. Hourdin
[5159]468
[5105]469  !    ********************************************************************
470  ! Shema  d'advection " pseudo amont " .
471  !    ********************************************************************
472  ! nq,iq,q,pbaru,pbarv,w sont des arguments d'entree  pour le s-pg ....
[5159]473
474
[5105]475  !   --------------------------------------------------------------------
[5118]476  USE lmdz_iniprint, ONLY: lunout, prt_level
[5159]477USE lmdz_dimensions, ONLY: iim, jjm, llm, ndm
478  USE lmdz_paramet
[5105]479  IMPLICIT NONE
480  !
[5159]481
482
483
484
[5105]485  !   Arguments:
486  !   ----------
[5116]487  INTEGER :: mode
[5118]488  REAL :: masse(ip1jmp1, llm)
489  REAL :: u_m(ip1jmp1, llm)
490  REAL :: q(ip1jmp1, llm), qd(ip1jmp1, llm), qg(ip1jmp1, llm)
[5159]491
[5105]492  !  Local
493  !   ---------
[5159]494
[5118]495  INTEGER :: i, j, ij, l, indu(ip1jmp1), niju, iju, ijq
496  INTEGER :: n0, nl(llm)
[5159]497
[5118]498  REAL :: new_m, zu_m, zdq, zz
499  REAL :: zsigg(ip1jmp1, llm), zsigd(ip1jmp1, llm), zsig
500  REAL :: u_mq(ip1jmp1, llm)
[524]501
[5118]502  REAL :: zm, zq, zsigm, zsigp, zqm, zqp, zu
[524]503
[5118]504  LOGICAL :: ladvplus(ip1jmp1, llm)
[524]505
[5116]506  REAL :: prec
[5105]507  save prec
[524]508
[5105]509  data prec/1.e-15/
[524]510
[5158]511  DO l = 1, llm
512    DO ij = iip2, ip1jm
[5118]513      zdq = qd(ij, l) - qg(ij, l)
514      ! if((qd(ij,l)-q(ij,l))*(q(ij,l)-qg(ij,l)).lt.0.) THEN
515      !    PRINT*,'probleme au point ij=',ij,'  l=',l
516      !    PRINT*,qd(ij,l),q(ij,l),qg(ij,l)
517      !    qd(ij,l)=q(ij,l)
518      !    qg(ij,l)=q(ij,l)
519      ! END IF
520      IF(abs(zdq)>prec) THEN
521        zsigd(ij, l) = (q(ij, l) - qg(ij, l)) / zdq
522        zsigg(ij, l) = 1. - zsigd(ij, l)
523        ! IF(.NOT.(zsigd(ij,l).ge.0..and.zsigd(ij,l).le.1. .AND.
524        !    s               zsigg(ij,l).ge.0..or.zsigg(ij,l).le.1.) ) THEN
525        !    PRINT*,'probleme au point ij=',ij,'  l=',l
526        !    PRINT*,'sigg=',zsigg(ij,l),'  sigd=',zsigd(ij,l)
527        !    PRINT*,'q d,c,g ',qd(ij,l),q(ij,l),qg(ij,l),zdq
528        !    stop
529        ! END IF
530      else
531        zsigd(ij, l) = 0.5
532        zsigg(ij, l) = 0.5
533        qd(ij, l) = q(ij, l)
534        qg(ij, l) = q(ij, l)
535      endif
536    enddo
537  enddo
[524]538
[5105]539  !   calcul de la pente maximum dans la maille en valeur absolue
[524]540
[5158]541  DO l = 1, llm
542    DO ij = iip2, ip1jm - 1
[5118]543      IF (u_m(ij, l)>=0.) THEN
544        zsigp = zsigd(ij, l)
545        zsigm = zsigg(ij, l)
546        zqp = qd(ij, l)
547        zqm = qg(ij, l)
548        zm = masse(ij, l)
549        zq = q(ij, l)
[5105]550      else
[5118]551        zsigm = zsigd(ij + 1, l)
552        zsigp = zsigg(ij + 1, l)
553        zqm = qd(ij + 1, l)
554        zqp = qg(ij + 1, l)
555        zm = masse(ij + 1, l)
556        zq = q(ij + 1, l)
[5105]557      endif
[5118]558      zu = abs(u_m(ij, l))
559      ladvplus(ij, l) = zu>zm
560      zsig = zu / zm
561      IF(zsig==0.) zsigp = 0.1
[5117]562      IF (mode==1) THEN
[5118]563        IF (zsig<=zsigp) THEN
564          u_mq(ij, l) = u_m(ij, l) * zqp
565        ELSE IF (mode==1) THEN
566          u_mq(ij, l) = &
567                  sign(zm, u_m(ij, l)) * (zsigp * zqp + (zsig - zsigp) * zqm)
568        endif
[5105]569      else
[5118]570        IF (zsig<=zsigp) THEN
571          u_mq(ij, l) = u_m(ij, l) * (zqp - 0.5 * zsig / zsigp * (zqp - zq))
572        else
573          zz = 0.5 * (zsig - zsigp) / zsigm
574          u_mq(ij, l) = sign(zm, u_m(ij, l)) * (0.5 * (zq + zqp) * zsigp &
575                  + (zsig - zsigp) * (zq + zz * (zqm - zq)))
576        endif
[5105]577      endif
[5116]578      ! IF(zsig.lt.0.) THEN
[5105]579      !    PRINT*,'au point ij=',ij,'  l=',l,'  sig=',zsig
580      !    stop
[5117]581      ! END IF
[5118]582    enddo
[5105]583  enddo
[524]584
[5158]585  DO l = 1, llm
586    DO ij = iip1 + iip1, ip1jm, iip1
[5118]587      u_mq(ij, l) = u_mq(ij - iim, l)
588      ladvplus(ij, l) = ladvplus(ij - iim, l)
589    enddo
[5105]590  enddo
[524]591
[5105]592  !=================================================================
593  !   SCHEMA SEMI-LAGRAGIEN EN X DANS LES REGIONS POLAIRES
594  !=================================================================
595  !   tris des regions a traiter
[5118]596  n0 = 0
[5158]597  DO l = 1, llm
[5118]598    nl(l) = 0
[5158]599    DO ij = iip2, ip1jm
[5118]600      IF(ladvplus(ij, l)) THEN
601        nl(l) = nl(l) + 1
602        u_mq(ij, l) = 0.
603      endif
604    enddo
605    n0 = n0 + nl(l)
[5105]606  enddo
[524]607
[5116]608  IF(n0>1) THEN
[5118]609    IF (prt_level > 9) WRITE(lunout, *) &
610            'Nombre de points pour lesquels on advect plus que le' &
611            , 'contenu de la maille : ', n0
[524]612
[5158]613    DO l = 1, llm
[5118]614      IF(nl(l)>0) THEN
615        iju = 0
616        !   indicage des mailles concernees par le traitement special
[5158]617        DO ij = iip2, ip1jm
[5118]618          IF(ladvplus(ij, l).AND.mod(ij, iip1)/=0) THEN
619            iju = iju + 1
620            indu(iju) = ij
621          endif
622        enddo
623        niju = iju
624        ! PRINT*,'niju,nl',niju,nl(l)
625
626        !  traitement des mailles
[5158]627        DO iju = 1, niju
[5118]628          ij = indu(iju)
629          j = (ij - 1) / iip1 + 1
630          zu_m = u_m(ij, l)
631          u_mq(ij, l) = 0.
632          IF(zu_m>0.) THEN
633            ijq = ij
634            i = ijq - (j - 1) * iip1
635            !   accumulation pour les mailles completements advectees
[5158]636            DO while(zu_m>masse(ijq, l))
[5118]637              u_mq(ij, l) = u_mq(ij, l) + q(ijq, l) * masse(ijq, l)
638              zu_m = zu_m - masse(ijq, l)
639              i = mod(i - 2 + iim, iim) + 1
640              ijq = (j - 1) * iip1 + i
641            enddo
642            !   MODIFS SPECIFIQUES DU SCHEMA
643            !   ajout de la maille non completement advectee
644            zsig = zu_m / masse(ijq, l)
645            IF(zsig<=zsigd(ijq, l)) THEN
646              u_mq(ij, l) = u_mq(ij, l) + zu_m * (qd(ijq, l) &
647                      - 0.5 * zsig / zsigd(ijq, l) * (qd(ijq, l) - q(ijq, l)))
648            else
649              ! u_mq(ij,l)=u_mq(ij,l)+zu_m*q(ijq,l)
650              ! goto 8888
651              zz = 0.5 * (zsig - zsigd(ijq, l)) / zsigg(ijq, l)
652              IF(.NOT.(zz>0..and.zz<=0.5)) THEN
653                WRITE(lunout, *)'probleme2 au point ij=', ij, &
654                        '  l=', l
655                WRITE(lunout, *)'zz=', zz
656                stop
[5105]657              endif
[5118]658              u_mq(ij, l) = u_mq(ij, l) + masse(ijq, l) * (&
659                      0.5 * (q(ijq, l) + qd(ijq, l)) * zsigd(ijq, l) &
660                              + (zsig - zsigd(ijq, l)) * (q(ijq, l) + zz * (qg(ijq, l) - q(ijq, l))))
[524]661            endif
[5118]662          else
663            ijq = ij + 1
664            i = ijq - (j - 1) * iip1
665            !   accumulation pour les mailles completements advectees
[5158]666            DO while(-zu_m>masse(ijq, l))
[5118]667              u_mq(ij, l) = u_mq(ij, l) - q(ijq, l) * masse(ijq, l)
668              zu_m = zu_m + masse(ijq, l)
669              i = mod(i, iim) + 1
670              ijq = (j - 1) * iip1 + i
671            enddo
672            !   ajout de la maille non completement advectee
673            ! 2eme MODIF SPECIFIQUE
674            zsig = -zu_m / masse(ij + 1, l)
675            IF(zsig<=zsigg(ijq, l)) THEN
676              u_mq(ij, l) = u_mq(ij, l) + zu_m * (qg(ijq, l) &
677                      - 0.5 * zsig / zsigg(ijq, l) * (qg(ijq, l) - q(ijq, l)))
678            else
679              ! u_mq(ij,l)=u_mq(ij,l)+zu_m*q(ijq,l)
680              ! goto 9999
681              zz = 0.5 * (zsig - zsigg(ijq, l)) / zsigd(ijq, l)
682              IF(.NOT.(zz>0..and.zz<=0.5)) THEN
683                WRITE(lunout, *)'probleme22 au point ij=', ij &
684                        , '  l=', l
685                WRITE(lunout, *)'zz=', zz
686                stop
687              endif
688              u_mq(ij, l) = u_mq(ij, l) - masse(ijq, l) * (&
689                      0.5 * (q(ijq, l) + qg(ijq, l)) * zsigg(ijq, l) &
690                              + (zsig - zsigg(ijq, l)) * &
691                              (q(ijq, l) + zz * (qd(ijq, l) - q(ijq, l))))
[5105]692            endif
[5118]693            !   fin de la modif
694          endif
695        enddo
696      endif
697    enddo
[5117]698  ENDIF  ! n0.gt.0
[524]699
[5105]700  !   bouclage en latitude
[5158]701  DO l = 1, llm
702    DO ij = iip1 + iip1, ip1jm, iip1
[5118]703      u_mq(ij, l) = u_mq(ij - iim, l)
[5105]704    enddo
705  enddo
[524]706
[5105]707  !=================================================================
708  !   CALCUL DE LA CONVERGENCE DES FLUX
709  !=================================================================
[524]710
[5158]711  DO l = 1, llm
712    DO ij = iip2 + 1, ip1jm
[5118]713      new_m = masse(ij, l) + u_m(ij - 1, l) - u_m(ij, l)
714      q(ij, l) = (q(ij, l) * masse(ij, l) + &
715              u_mq(ij - 1, l) - u_mq(ij, l)) &
716              / new_m
717      masse(ij, l) = new_m
718    enddo
719    !   Modif Fred 22 03 96 correction d'un bug (les scopy ci-dessous)
[5158]720    DO ij = iip1 + iip1, ip1jm, iip1
[5118]721      q(ij - iim, l) = q(ij, l)
722      masse(ij - iim, l) = masse(ij, l)
723    enddo
[5105]724  enddo
[524]725
[5105]726  RETURN
727END SUBROUTINE advnx
[5118]728SUBROUTINE advny(q, qs, qn, masse, v_m)
[5159]729
[5105]730  ! Auteur : F. Hourdin
[5159]731
[5105]732  !    ********************************************************************
733  ! Shema  d'advection " pseudo amont " .
734  !    ********************************************************************
735  ! nq,iq,q,pbaru,pbarv,w sont des arguments d'entree  pour le s-pg ....
[5159]736
737
[5105]738  !   --------------------------------------------------------------------
[5118]739  USE lmdz_iniprint, ONLY: lunout, prt_level
[5123]740  USE lmdz_ssum_scopy, ONLY: ssum
[5136]741  USE lmdz_comgeom
[5123]742
[5159]743USE lmdz_dimensions, ONLY: iim, jjm, llm, ndm
744  USE lmdz_paramet
[5105]745  IMPLICIT NONE
746  !
[5159]747
748
749
750
[5105]751  !   Arguments:
752  !   ----------
[5118]753  REAL :: masse(ip1jmp1, llm)
754  REAL :: v_m(ip1jm, llm)
755  REAL :: q(ip1jmp1, llm), qn(ip1jmp1, llm), qs(ip1jmp1, llm)
[5159]756
[5105]757  !  Local
758  !   ---------
[5159]759
[5118]760  INTEGER :: ij, l
[5159]761
[5118]762  REAL :: new_m, zdq, zz
763  REAL :: zsigs(ip1jmp1), zsign(ip1jmp1), zsig
764  REAL :: v_mq(ip1jm, llm)
765  REAL :: convpn, convps, convmpn, convmps, massen, masses
766  REAL :: zm, zq, zsigm, zsigp, zqm, zqp
[5116]767  REAL :: prec
[5105]768  save prec
[524]769
[5105]770  data prec/1.e-15/
[5158]771  DO l = 1, llm
772    DO ij = 1, ip1jmp1
[5118]773      zdq = qn(ij, l) - qs(ij, l)
774      ! if((qn(ij,l)-q(ij,l))*(q(ij,l)-qs(ij,l)).lt.0.) THEN
775      !    PRINT*,'probleme au point ij=',ij,'  l=',l,'  advnqx'
776      !    PRINT*,qn(ij,l),q(ij,l),qs(ij,l)
777      !    qn(ij,l)=q(ij,l)
778      !    qs(ij,l)=q(ij,l)
779      ! END IF
780      IF(abs(zdq)>prec) THEN
781        zsign(ij) = (q(ij, l) - qs(ij, l)) / zdq
782        zsigs(ij) = 1. - zsign(ij)
783        ! IF(.NOT.(zsign(ij).ge.0..and.zsign(ij).le.1. .AND.
784        !    s               zsigs(ij).ge.0..or.zsigs(ij).le.1.) ) THEN
785        !    PRINT*,'probleme au point ij=',ij,'  l=',l
786        !    PRINT*,'sigs=',zsigs(ij),'  sign=',zsign(ij)
787        !    stop
788        ! END IF
789      else
790        zsign(ij) = 0.5
791        zsigs(ij) = 0.5
792      endif
793    enddo
[524]794
[5118]795    !   calcul de la pente maximum dans la maille en valeur absolue
[524]796
[5158]797    DO ij = 1, ip1jm
[5118]798      IF (v_m(ij, l)>=0.) THEN
799        zsigp = zsign(ij + iip1)
800        zsigm = zsigs(ij + iip1)
801        zqp = qn(ij + iip1, l)
802        zqm = qs(ij + iip1, l)
803        zm = masse(ij + iip1, l)
804        zq = q(ij + iip1, l)
[5105]805      else
[5118]806        zsigm = zsign(ij)
807        zsigp = zsigs(ij)
808        zqm = qn(ij, l)
809        zqp = qs(ij, l)
810        zm = masse(ij, l)
811        zq = q(ij, l)
[5105]812      endif
[5118]813      zsig = abs(v_m(ij, l)) / zm
814      IF(zsig==0.) zsigp = 0.1
[5117]815      IF (zsig<=zsigp) THEN
[5118]816        v_mq(ij, l) = v_m(ij, l) * (zqp - 0.5 * zsig / zsigp * (zqp - zq))
[5105]817      else
[5118]818        zz = 0.5 * (zsig - zsigp) / zsigm
819        v_mq(ij, l) = sign(zm, v_m(ij, l)) * (0.5 * (zq + zqp) * zsigp &
820                + (zsig - zsigp) * (zq + zz * (zqm - zq)))
[5105]821      endif
[5118]822    enddo
[5105]823  enddo
[524]824
[5158]825  DO l = 1, llm
826    DO ij = iip2, ip1jm
[5118]827      new_m = masse(ij, l) &
828              + v_m(ij, l) - v_m(ij - iip1, l)
829      q(ij, l) = (q(ij, l) * masse(ij, l) + v_mq(ij, l) - v_mq(ij - iip1, l)) &
830              / new_m
831      masse(ij, l) = new_m
832    enddo
833    !.-. ancienne version
834    convpn = SSUM(iim, v_mq(1, l), 1)
835    convmpn = ssum(iim, v_m(1, l), 1)
836    massen = ssum(iim, masse(1, l), 1)
837    new_m = massen + convmpn
838    q(1, l) = (q(1, l) * massen + convpn) / new_m
[5158]839    DO ij = 1, iip1
[5118]840      q(ij, l) = q(1, l)
841      masse(ij, l) = new_m * aire(ij) / apoln
842    enddo
[524]843
[5118]844    convps = -SSUM(iim, v_mq(ip1jm - iim, l), 1)
845    convmps = -ssum(iim, v_m(ip1jm - iim, l), 1)
846    masses = ssum(iim, masse(ip1jm + 1, l), 1)
847    new_m = masses + convmps
848    q(ip1jm + 1, l) = (q(ip1jm + 1, l) * masses + convps) / new_m
[5158]849    DO ij = ip1jm + 1, ip1jmp1
[5118]850      q(ij, l) = q(ip1jm + 1, l)
851      masse(ij, l) = new_m * aire(ij) / apols
852    enddo
[5105]853  enddo
[524]854
[5105]855  RETURN
856END SUBROUTINE advny
[5118]857SUBROUTINE advnz(q, qh, qb, masse, w_m)
[5159]858
[5105]859  ! Auteurs:   F.Hourdin
[5159]860
[5105]861  !    ********************************************************************
862  ! Shema  d'advection " pseudo amont " .
863  ! b designe le bas et h le haut
864  ! il y a une correspondance entre le b en z et le d en x
865  !    ********************************************************************
[5159]866
867
[5105]868  !   --------------------------------------------------------------------
[5118]869  USE lmdz_iniprint, ONLY: lunout, prt_level
[5136]870  USE lmdz_comgeom
871
[5159]872USE lmdz_dimensions, ONLY: iim, jjm, llm, ndm
873  USE lmdz_paramet
[5105]874  IMPLICIT NONE
875  !
[5159]876
877
878
879
[5105]880  !   Arguments:
881  !   ----------
[5118]882  REAL :: masse(ip1jmp1, llm)
883  REAL :: w_m(ip1jmp1, llm + 1)
884  REAL :: q(ip1jmp1, llm), qb(ip1jmp1, llm), qh(ip1jmp1, llm)
[524]885
[5159]886
[5105]887  !  Local
888  !   ---------
[5159]889
[5118]890  INTEGER :: ij, l
[5159]891
[5118]892  REAL :: new_m, zdq, zz
893  REAL :: zsigh(ip1jmp1, llm), zsigb(ip1jmp1, llm), zsig
894  REAL :: w_mq(ip1jmp1, llm + 1)
895  REAL :: zm, zq, zsigm, zsigp, zqm, zqp
[5116]896  REAL :: prec
[5105]897  save prec
[524]898
[5105]899  data prec/1.e-13/
[524]900
[5158]901  DO l = 1, llm
902    DO ij = 1, ip1jmp1
[5118]903      zdq = qb(ij, l) - qh(ij, l)
904      ! if((qh(ij,l)-q(ij,l))*(q(ij,l)-qb(ij,l)).lt.0.) THEN
905      !    PRINT*,'probleme au point ij=',ij,'  l=',l
906      !    PRINT*,qh(ij,l),q(ij,l),qb(ij,l)
907      !    qh(ij,l)=q(ij,l)
908      !    qb(ij,l)=q(ij,l)
909      ! END IF
[524]910
[5118]911      IF(abs(zdq)>prec) THEN
912        zsigb(ij, l) = (q(ij, l) - qh(ij, l)) / zdq
913        zsigh(ij, l) = 1. - zsigb(ij, l)
914        zsigb(ij, l) = min(max(zsigb(ij, l), 0.), 1.)
915      else
916        zsigb(ij, l) = 0.5
917        zsigh(ij, l) = 0.5
918      endif
919    enddo
920  enddo
[524]921
[5118]922  ! PRINT*,'ok1'
[5105]923  !   calcul de la pente maximum dans la maille en valeur absolue
[5158]924  DO l = 2, llm
925    DO ij = 1, ip1jmp1
[5118]926      IF (w_m(ij, l)>=0.) THEN
927        zsigp = zsigb(ij, l)
928        zsigm = zsigh(ij, l)
929        zqp = qb(ij, l)
930        zqm = qh(ij, l)
931        zm = masse(ij, l)
932        zq = q(ij, l)
[5105]933      else
[5118]934        zsigm = zsigb(ij, l - 1)
935        zsigp = zsigh(ij, l - 1)
936        zqm = qb(ij, l - 1)
937        zqp = qh(ij, l - 1)
938        zm = masse(ij, l - 1)
939        zq = q(ij, l - 1)
[5105]940      endif
[5118]941      zsig = abs(w_m(ij, l)) / zm
942      IF(zsig==0.) zsigp = 0.1
[5117]943      IF (zsig<=zsigp) THEN
[5118]944        w_mq(ij, l) = w_m(ij, l) * (zqp - 0.5 * zsig / zsigp * (zqp - zq))
[5105]945      else
[5118]946        zz = 0.5 * (zsig - zsigp) / zsigm
947        w_mq(ij, l) = sign(zm, w_m(ij, l)) * (0.5 * (zq + zqp) * zsigp &
948                + (zsig - zsigp) * (zq + zz * (zqm - zq)))
[5105]949      endif
[5118]950    enddo
[5105]951  enddo
[5118]952
[5158]953  DO ij = 1, ip1jmp1
[5118]954    w_mq(ij, llm + 1) = 0.
955    w_mq(ij, 1) = 0.
[5105]956  enddo
[524]957
[5158]958  DO l = 1, llm
959    DO ij = 1, ip1jmp1
[5118]960      new_m = masse(ij, l) + w_m(ij, l + 1) - w_m(ij, l)
961      q(ij, l) = (q(ij, l) * masse(ij, l) + w_mq(ij, l + 1) - w_mq(ij, l)) &
962              / new_m
963      masse(ij, l) = new_m
964    enddo
[5105]965  enddo
966  ! PRINT*,'ok3'
967  RETURN
968END SUBROUTINE advnz
Note: See TracBrowser for help on using the repository browser.