source: LMDZ5/trunk/libf/phylmd/clouds_gno.F @ 1723

Last change on this file since 1723 was 1279, checked in by Laurent Fairhead, 15 years ago

Merged LMDZ4-dev branch changes r1241:1278 into the trunk
Running trunk and LMDZ4-dev in LMDZOR configuration on local
machine (sequential) and SX8 (4-proc) yields identical results
(restart and restartphy are identical binarily)
Log history from r1241 to r1278 is available by switching to
source:LMDZ4/branches/LMDZ4-dev-20091210

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.2 KB
Line 
1!
2! $Header$
3!
4C
5C================================================================================
6C
7      SUBROUTINE CLOUDS_GNO(klon,ND,R,RS,QSUB,PTCONV,RATQSC,CLDF)
8      IMPLICIT NONE
9C     
10C--------------------------------------------------------------------------------
11C
12C Inputs:
13C
14C  ND----------: Number of vertical levels
15C  R--------ND-: Domain-averaged mixing ratio of total water
16C  RS-------ND-: Mean saturation humidity mixing ratio within the gridbox
17C  QSUB-----ND-: Mixing ratio of condensed water within clouds associated
18C                with SUBGRID-SCALE condensation processes (here, it is
19C                predicted by the convection scheme)
20C Outputs:
21C
22C  PTCONV-----ND-: Point convectif = TRUE
23C  RATQSC-----ND-: Largeur normalisee de la distribution
24C  CLDF-----ND-: Fraction nuageuse
25C
26C--------------------------------------------------------------------------------
27
28
29      INTEGER klon,ND
30      REAL R(klon,ND),  RS(klon,ND), QSUB(klon,ND)
31      LOGICAL PTCONV(klon,ND)
32      REAL RATQSC(klon,ND)
33      REAL CLDF(klon,ND)
34
35c -- parameters controlling the iteration:
36c --    nmax    : maximum nb of iterations (hopefully never reached)
37c --    epsilon : accuracy of the numerical resolution
38c --    vmax    : v-value above which we use an asymptotic expression for ERF(v)
39
40      INTEGER nmax
41      PARAMETER ( nmax = 10)
42      REAL epsilon, vmax0, vmax(klon)
43      PARAMETER ( epsilon = 0.02, vmax0 = 2.0 )
44
45      REAL min_mu, min_Q
46      PARAMETER ( min_mu =  1.e-12, min_Q=1.e-12 )
47     
48      INTEGER i,K, n, m
49      REAL mu(klon), qsat, delta(klon), beta(klon)
50      real zu2,zv2
51      REAL xx(klon), aux(klon), coeff, block
52      REAL  dist, fprime, det
53      REAL pi, u, v, erfcu, erfcv
54      REAL  xx1, xx2
55      real erf,hsqrtlog_2,v2
56      real sqrtpi,sqrt2,zx1,zx2,exdel
57c lconv = true si le calcul a converge (entre autre si qsub < min_q)
58       LOGICAL lconv(klon)
59
60!cdir arraycomb
61      cldf  (1:klon,1:ND)=0.0        ! cym
62      ratqsc(1:klon,1:ND)=0.0
63      ptconv(1:klon,1:ND)=.false.
64!cdir end arraycomb
65     
66      pi = ACOS(-1.)
67      sqrtpi=sqrt(pi)
68      sqrt2=sqrt(2.)
69      hsqrtlog_2=0.5*SQRT(log(2.))
70
71      DO 500 K = 1, ND
72
73                                    do i=1,klon ! vector
74      mu(i) = R(i,K)
75      mu(i) = MAX(mu(i),min_mu)
76      qsat = RS(i,K)
77      qsat = MAX(qsat,min_mu)
78      delta(i) = log(mu(i)/qsat)
79c                                   enddo ! vector
80
81C
82C ***          There is no subgrid-scale condensation;        ***
83C ***   the scheme becomes equivalent to an "all-or-nothing"  ***
84C ***             large-scale condensation scheme.            ***
85C
86
87C
88C ***     Some condensation is produced at the subgrid-scale       ***
89C ***                                                              ***
90C ***       PDF = generalized log-normal distribution (GNO)        ***
91C ***   (k<0 because a lower bound is considered for the PDF)      ***
92C ***                                                              ***
93C ***  -> Determine x (the parameter k of the GNO PDF) such        ***
94C ***  that the contribution of subgrid-scale processes to         ***
95C ***  the in-cloud water content is equal to QSUB(K)              ***
96C ***  (equations (13), (14), (15) + Appendix B of the paper)      ***
97C ***                                                              ***
98C ***    Here, an iterative method is used for this purpose        ***
99C ***    (other numerical methods might be more efficient)         ***
100C ***                                                              ***
101C ***          NB: the "error function" is called ERF              ***
102C ***                 (ERF in double precision)                   ***
103C
104
105c  On commence par eliminer les cas pour lesquels on n'a pas
106c  suffisamment d'eau nuageuse.
107
108c                                   do i=1,klon ! vector
109
110      IF ( QSUB(i,K) .lt. min_Q ) THEN
111        ptconv(i,k)=.false.
112        ratqsc(i,k)=0.
113        lconv(i)  = .true.
114
115c   Rien on a deja initialise
116
117      ELSE
118
119        lconv(i)  = .FALSE.
120        vmax(i) = vmax0
121
122        beta(i) = QSUB(i,K)/mu(i) + EXP( -MIN(0.0,delta(i)) )
123
124c --  roots of equation v > vmax:
125
126        det = delta(i) + vmax(i)*vmax(i)
127        if (det.LE.0.0) vmax(i) = vmax0 + 1.0
128        det = delta(i) + vmax(i)*vmax(i)
129
130        if (det.LE.0.) then
131          xx(i) = -0.0001
132        else
133         zx1=-sqrt2*vmax(i)
134         zx2=SQRT(1.0+delta(i)/(vmax(i)*vmax(i)))
135         xx1=zx1*(1.0-zx2)
136         xx2=zx1*(1.0+zx2)
137         xx(i) = 1.01 * xx1
138         if ( xx1 .GE. 0.0 ) xx(i) = 0.5*xx2
139        endif
140        if (delta(i).LT.0.) xx(i) = -hsqrtlog_2
141
142      ENDIF
143
144                                    enddo       ! vector
145
146c----------------------------------------------------------------------
147c   Debut des nmax iterations pour trouver la solution.
148c----------------------------------------------------------------------
149
150      DO n = 1, nmax
151
152                                    do i=1,klon ! vector
153        if (.not.lconv(i)) then
154
155          u = delta(i)/(xx(i)*sqrt2) + xx(i)/(2.*sqrt2)
156          v = delta(i)/(xx(i)*sqrt2) - xx(i)/(2.*sqrt2)
157          v2 = v*v
158
159          IF ( v .GT. vmax(i) ) THEN
160
161            IF (     ABS(u)  .GT. vmax(i)
162     :          .AND.  delta(i) .LT. 0. ) THEN
163
164c -- use asymptotic expression of erf for u and v large:
165c ( -> analytic solution for xx )
166             exdel=beta(i)*EXP(delta(i))
167             aux(i) = 2.0*delta(i)*(1.-exdel)
168     :                       /(1.+exdel)
169             if (aux(i).lt.0.) then
170c                print*,'AUX(',i,',',k,')<0',aux(i),delta(i),beta(i)
171                aux(i)=0.
172             endif
173             xx(i) = -SQRT(aux(i))
174             block = EXP(-v*v) / v / sqrtpi
175             dist = 0.0
176             fprime = 1.0
177
178            ELSE
179
180c -- erfv -> 1.0, use an asymptotic expression of erfv for v large:
181
182             erfcu = 1.0-ERF(u)
183c  !!! ATTENTION : rajout d'un seuil pour l'exponentiel
184             aux(i) = sqrtpi*erfcu*EXP(min(v2,100.))
185             coeff = 1.0 - 0.5/(v2) + 0.75/(v2*v2)
186             block = coeff * EXP(-v2) / v / sqrtpi
187             dist = v * aux(i) / coeff - beta(i)
188             fprime = 2.0 / xx(i) * (v2)
189     :           * ( EXP(-delta(i)) - u * aux(i) / coeff )
190     :           / coeff
191           
192            ENDIF ! ABS(u)
193
194          ELSE
195
196c -- general case:
197
198           erfcu = 1.0-ERF(u)
199           erfcv = 1.0-ERF(v)
200           block = erfcv
201           dist = erfcu / erfcv - beta(i)
202           zu2=u*u
203           zv2=v2
204           if(zu2.gt.20..or. zv2.gt.20.) then
205c              print*,'ATTENTION !!! xx(',i,') =', xx(i)
206c           print*,'ATTENTION !!! klon,ND,R,RS,QSUB,PTCONV,RATQSC,CLDF',
207c     .klon,ND,R(i,k),RS(i,k),QSUB(i,k),PTCONV(i,k),RATQSC(i,k),
208c     .CLDF(i,k)
209c              print*,'ATTENTION !!! zu2 zv2 =',zu2(i),zv2(i)
210              zu2=20.
211              zv2=20.
212             fprime = 0.
213           else
214             fprime = 2. /sqrtpi /xx(i) /(erfcv*erfcv)
215     :           * (   erfcv*v*EXP(-zu2)
216     :               - erfcu*u*EXP(-zv2) )
217           endif
218          ENDIF ! x
219
220c -- test numerical convergence:
221
222!          if (beta(i).lt.1.e-10) then
223!              print*,'avant test ',i,k,lconv(i),u(i),v(i),beta(i)
224!              stop
225!          endif
226          if (abs(fprime).lt.1.e-11) then
227!              print*,'avant test fprime<.e-11 '
228!     s        ,i,k,lconv(i),u(i),v(i),beta(i),fprime(i)
229!              print*,'klon,ND,R,RS,QSUB',
230!     s        klon,ND,R(i,k),rs(i,k),qsub(i,k)
231              fprime=sign(1.e-11,fprime)
232          endif
233
234
235          if ( ABS(dist/beta(i)) .LT. epsilon ) then
236c           print*,'v-u **2',(v(i)-u(i))**2
237c           print*,'exp v-u **2',exp((v(i)-u(i))**2)
238            ptconv(i,K) = .TRUE.
239            lconv(i)=.true.
240c  borne pour l'exponentielle
241            ratqsc(i,k)=min(2.*(v-u)*(v-u),20.)
242            ratqsc(i,k)=sqrt(exp(ratqsc(i,k))-1.)
243            CLDF(i,K) = 0.5 * block
244          else
245            xx(i) = xx(i) - dist/fprime
246          endif
247c         print*,'apres test ',i,k,lconv(i)
248
249        endif ! lconv
250                                    enddo       ! vector
251
252c----------------------------------------------------------------------
253c   Fin des nmax iterations pour trouver la solution.
254        ENDDO ! n
255c----------------------------------------------------------------------
256
257500   CONTINUE  ! K
258
259       RETURN
260       END
261
262 
263
Note: See TracBrowser for help on using the repository browser.