source: LMDZ6/trunk/libf/dyn3d/qminimum.F @ 5006

Last change on this file since 5006 was 5001, checked in by dcugnet, 6 months ago
  • strings_mod:
    • remove "test()" function (was not very clear)
    • modifications of the "str2bool" function: result is O/1 for .FALSE./.TRUE. and -1 if the string was not a boolean.
    • more general "find()" function (for several numerical types)
    • more general "cat()" function (can append a 2D array with vectors, 1D arrays with scalars)
    • few simplifications (in "strParse") and minor changes
  • readTracFiles_mod:
    • remove internal usage of direct keys ("%" symbol) in favor of the "getKey" function. => moving toward a totally generic tracers derived type.
    • improve the internal management of the error return value "lerr".
    • remove "fGetKey", "fGetKeys", "setDirectKeys" functions
    • new functions to add/remove a phase: "addPhase", "delPhase"
    • more general "addKey(key[(:)], val[(:)], ky(:), [lOverWrite])" function: . input argument "val" can be string/integer/real/logical . (key, val, ky ): add the <key> =<val> pair to ky . (key, val(:), ky(:)): add the <key> =<val(i)> pair to ky(i) for 1<=i<=SIZE(ky) . (key(:), val(:), ky(:)): add the <key(i)>=<val(i)> pair to ky(i) for 1<=i<=SIZE(ky)
    • more general "getKey(key[(:)], val[(:)], itr [, ky(:)][, nam(:)][, def][, lDisp])" (tracer index version)

and "getKey(key[(:)], val[(:)], tname[, ky(:)]. [, def][, lDisp])" (tracer name version) functions:

. output argument "val" can be string/integer/real/logical
. if present, the default value <def> is retained if the corresponding key was not found.
. get values from "ky(:)" if present, otherwise from internal database "tracers(:)" or "isotope ».
. if "keyn" is a vector, try with each element in indices order until a value is found
. (key[(:)], val, itr/tname[,ky(:)][, ...]): get the value <val> of tracer nr. itr or named "tname"
. (key[(:)], val(:), itr/tname[,ky(:)][, ...]): same + parsing of the value with « , », then storage in <val(:)>
. (key[(:)], val(:)[, ky(:)][, nam(:)][, ...]): same for all tracers (optional names list <nam(:)>) of database.
. (key[(:)], val(:), tname(:)[, ky(:)][, ...]): same for the tracers named « tnames(:)"

  • more general "dispTraSection" function
  • much simplified "indexUpdate" function ; "ancestor*" and "idxAncestor" functions are removed.
  • "readIsotopesFile" is renamed to "processIsotopes" for more clarity
  • cosmetic changes
  • fix for isotopes: iq_val and iq_liq are usable for "q" only, not for "q_follow" and "zx_defau_diag" => use hardcoded indices (1 for vapor and 2 for liquid) for these variables
  • 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: 6.5 KB
Line 
1!
2! $Header$
3!
4      SUBROUTINE qminimum( q,nqtot,deltap )
5
6      USE infotrac, ONLY: niso, ntiso,iqIsoPha, tracers
7      USE strings_mod, ONLY: strIdx
8      USE readTracFiles_mod, ONLY: addPhase
9      IMPLICIT none
10c
11c  -- Objet : Traiter les valeurs trop petites (meme negatives)
12c             pour l'eau vapeur et l'eau liquide
13c
14      include "dimensions.h"
15      include "paramet.h"
16c
17      INTEGER nqtot
18      REAL q(ip1jmp1,llm,nqtot), deltap(ip1jmp1,llm)
19c
20      LOGICAL, SAVE :: first=.TRUE.
21      INTEGER, SAVE :: iq_vap, iq_liq        ! indices pour l'eau vapeur/liquide
22      REAL, PARAMETER :: seuil_vap = 1.0e-10 ! seuil pour l'eau vapeur
23      REAL, PARAMETER :: seuil_liq = 1.0e-11 ! seuil pour l'eau liquide
24c
25c  NB. ....( Il est souhaitable mais non obligatoire que les valeurs des
26c            parametres seuil_vap, seuil_liq soient pareilles a celles
27c            qui  sont utilisees dans la routine    ADDFI       )
28c     .................................................................
29c
30cDC iq_val and iq_liq are usable for q only, NOT for q_follow
31c   and zx_defau_diag (crash if iq_val/liq==3) => vapor/liquid
32c   water at hardcoded indices 1/2 in these variables
33      INTEGER i, k, iq
34      REAL zx_defau, zx_abc, zx_pump(ip1jmp1), pompe
35
36      real zx_defau_diag(ip1jmp1,llm,2)
37      real q_follow(ip1jmp1,llm,2)
38c
39      REAL SSUM
40c
41      INTEGER imprim
42      SAVE imprim
43      DATA imprim /0/
44      !INTEGER ijb,ije
45      !INTEGER Index_pump(ij_end-ij_begin+1)
46      !INTEGER nb_pump
47      INTEGER ixt
48
49      IF(first) THEN
50         iq_vap = strIdx(tracers(:)%name, addPhase('H2O', 'g'))
51         iq_liq = strIdx(tracers(:)%name, addPhase('H2O', 'l'))
52         first = .FALSE.
53      END IF
54c
55c Quand l'eau liquide est trop petite (ou negative), on prend
56c l'eau vapeur de la meme couche et la convertit en eau liquide
57c (sans changer la temperature !)
58c
59
60      call check_isotopes_seq(q,ip1jmp1,'qminimum 52')   
61
62      zx_defau_diag(:,:,:)=0.0
63      q_follow(:,:,1)=q(:,:,iq_vap) 
64      q_follow(:,:,2)=q(:,:,iq_liq) 
65      DO k = 1, llm
66        DO i = 1, ip1jmp1
67          if (seuil_liq - q(i,k,iq_liq) .gt. 0.d0 ) then
68
69            if (niso > 0) zx_defau_diag(i,k,2)=AMAX1
70     :               ( seuil_liq - q(i,k,iq_liq), 0.0 )
71
72            q(i,k,iq_vap) = q(i,k,iq_vap) + q(i,k,iq_liq) - seuil_liq
73            q(i,k,iq_liq) = seuil_liq
74          endif
75        ENDDO
76      ENDDO
77c
78c Quand l'eau vapeur est trop faible (ou negative), on complete
79c le defaut en prennant de l'eau vapeur de la couche au-dessous.
80c
81      DO k = llm, 2, -1
82ccc      zx_abc = dpres(k) / dpres(k-1)
83        DO i = 1, ip1jmp1
84          if ( seuil_vap - q(i,k,iq_vap) .gt. 0.d0 ) then
85
86            if (niso > 0) zx_defau_diag(i,k,1)
87     &           = AMAX1( seuil_vap - q(i,k,iq_vap), 0.0 )
88
89            q(i,k-1,iq_vap) = q(i,k-1,iq_vap) - (seuil_vap
90     &           -q(i,k,iq_vap)) * deltap(i,k)/deltap(i,k-1)
91            q(i,k,iq_vap)   =  seuil_vap 
92
93          endif
94        ENDDO
95      ENDDO
96
97c
98c Quand il s'agit de la premiere couche au-dessus du sol, on
99c doit imprimer un message d'avertissement (saturation possible).
100c
101      DO i = 1, ip1jmp1
102         zx_pump(i) = AMAX1( 0.0, seuil_vap - q(i,1,iq_vap) )
103         q(i,1,iq_vap)  = AMAX1( q(i,1,iq_vap), seuil_vap )
104      ENDDO
105      pompe = SSUM(ip1jmp1,zx_pump,1)
106      IF (imprim.LE.500 .AND. pompe.GT.0.0) THEN
107         WRITE(6,'(1x,"ATT!:on pompe de l eau au sol",e15.7)') pompe
108         DO i = 1, ip1jmp1
109            IF (zx_pump(i).GT.0.0) THEN
110               imprim = imprim + 1
111               PRINT*,'QMINIMUM:  en ',i,zx_pump(i)
112            ENDIF
113         ENDDO
114      ENDIF
115
116      !write(*,*) 'qminimum 128'
117      if (niso > 0) then
118      ! CRisi: traiter de même les traceurs d'eau
119      ! Mais il faut les prendre à l'envers pour essayer de conserver la
120      ! masse.
121      ! 1) pompage dans le sol 
122      ! On suppose que ce pompage se fait sans isotopes -> on ne modifie
123      ! rien ici et on croise les doigts pour que ça ne soit pas trop
124      ! génant
125      DO i = 1,ip1jmp1
126        if (zx_pump(i).gt.0.0) then
127          q_follow(i,1,1)=q_follow(i,1,1)+zx_pump(i)
128        endif !if (zx_pump(i).gt.0.0) then
129      enddo !DO i = 1,ip1jmp1
130
131      ! 2) transfert de vap vers les couches plus hautes
132      !write(*,*) 'qminimum 139'
133      do k=2,llm
134        DO i = 1,ip1jmp1
135          if (zx_defau_diag(i,k,1).gt.0.0) then             
136              ! on ajoute la vapeur en k             
137              do ixt=1,ntiso
138               q(i,k,iqIsoPha(ixt,iq_vap))=q(i,k,iqIsoPha(ixt,iq_vap))
139     :           +zx_defau_diag(i,k,1)
140     :           *q(i,k-1,iqIsoPha(ixt,iq_vap))/q_follow(i,k-1,1)
141               
142              ! et on la retranche en k-1
143               q(i,k-1,iqIsoPha(ixt,iq_vap))=
144     :            q(i,k-1,iqIsoPha(ixt,iq_vap))
145     :              -zx_defau_diag(i,k,1)
146     :              *deltap(i,k)/deltap(i,k-1)
147     :              *q(i,k-1,iqIsoPha(ixt,iq_vap))
148     :              /q_follow(i,k-1,1)
149
150              enddo !do ixt=1,niso
151              q_follow(i,k,1)=   q_follow(i,k,1)
152     :               +zx_defau_diag(i,k,1)
153              q_follow(i,k-1,1)=   q_follow(i,k-1,1)
154     :               -zx_defau_diag(i,k,1)
155     :              *deltap(i,k)/deltap(i,k-1)
156          endif !if (zx_defau_diag(i,k,1).gt.0.0) then
157        enddo !DO i = 1, ip1jmp1       
158       enddo !do k=2,llm
159
160       call check_isotopes_seq(q,ip1jmp1,'qminimum 168')
161       
162     
163        ! 3) transfert d'eau de la vapeur au liquide
164        !write(*,*) 'qminimum 164'
165        do k=1,llm
166        DO i = 1,ip1jmp1
167          if (zx_defau_diag(i,k,2).gt.0.0) then
168
169              ! on ajoute eau liquide en k en k             
170              do ixt=1,ntiso
171               q(i,k,iqIsoPha(ixt,iq_liq))=q(i,k,iqIsoPha(ixt,iq_liq))
172     :              +zx_defau_diag(i,k,2)
173     :              *q(i,k,iqIsoPha(ixt,iq_vap))/q_follow(i,k,1)
174              ! et on la retranche à la vapeur en k
175               q(i,k,iqIsoPha(ixt,iq_vap))=q(i,k,iqIsoPha(ixt,iq_vap))
176     :              -zx_defau_diag(i,k,2)
177     :              *q(i,k,iqIsoPha(ixt,iq_vap))/q_follow(i,k,1)   
178              enddo !do ixt=1,niso
179              q_follow(i,k,2)=   q_follow(i,k,2)
180     :               +zx_defau_diag(i,k,2)
181              q_follow(i,k,1)=   q_follow(i,k,1)
182     :               -zx_defau_diag(i,k,2)
183          endif !if (zx_defau_diag(i,k,1).gt.0.0) then
184        enddo !DO i = 1, ip1jmp1
185       enddo !do k=2,llm 
186
187       call check_isotopes_seq(q,ip1jmp1,'qminimum 197')
188
189      endif !if (niso > 0) then
190      !write(*,*) 'qminimum 188'
191     
192c
193      RETURN
194      END
Note: See TracBrowser for help on using the repository browser.