/[lmdze]/trunk/Sources/phylmd/CV30_routines/cv30_unsat.f
ViewVC logotype

Diff of /trunk/Sources/phylmd/CV30_routines/cv30_unsat.f

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 189 by guez, Tue Mar 29 15:20:23 2016 UTC revision 194 by guez, Thu May 12 14:35:35 2016 UTC
# Line 9  contains Line 9  contains
9         evap, b)         evap, b)
10    
11      use cv30_param_m, only: nl, sigd      use cv30_param_m, only: nl, sigd
12      use cvthermo, only: cpd, ginv, grav      use cv_thermo_m, only: cpd, ginv, grav
13      USE dimphy, ONLY: klon, klev      USE dimphy, ONLY: klon, klev
14    
15      ! inputs:      integer, intent(in):: icb(:) ! (ncum)
16      integer, intent(in):: icb(:), inb(:) ! (ncum)  
17        integer, intent(in):: inb(:) ! (ncum)
18        ! first model level above the level of neutral buoyancy of the
19        ! parcel (1 <= inb <= nl - 1)
20    
21      real, intent(in):: t(:, :), q(:, :), qs(:, :) ! (klon, klev)      real, intent(in):: t(:, :), q(:, :), qs(:, :) ! (klon, klev)
22      real, intent(in):: gz(:, :) ! (klon, klev)      real, intent(in):: gz(:, :) ! (klon, klev)
23      real, intent(in):: u(:, :), v(:, :) ! (klon, klev)      real, intent(in):: u(:, :), v(:, :) ! (klon, klev)
24      real p(klon, klev), ph(klon, klev + 1)      real, intent(in):: p(klon, klev), ph(klon, klev + 1)
25      real th(klon, klev)      real, intent(in):: th(klon, klev)
26      real tv(klon, klev)      real, intent(in):: tv(klon, klev)
27      real lv(klon, klev)      real, intent(in):: lv(klon, klev)
28      real cpn(klon, klev)      real, intent(in):: cpn(klon, klev)
29      real, intent(in):: ep(klon, klev), sigp(klon, klev), clw(klon, klev)      real, intent(in):: ep(:, :), sigp(:, :), clw(:, :) ! (ncum, klev)
30      real m(klon, klev), ment(klon, klev, klev), elij(klon, klev, klev)      real, intent(in):: m(:, :) ! (ncum, klev)
31        real, intent(in):: ment(:, :, :) ! (ncum, klev, klev)
32        real, intent(in):: elij(:, :, :) ! (ncum, klev, klev)
33      real, intent(in):: delt      real, intent(in):: delt
34      real plcl(klon)      real, intent(in):: plcl(klon)
35    
36      ! outputs:      ! outputs:
37      real, intent(out):: mp(klon, klev)      real, intent(out):: mp(klon, klev)
# Line 35  contains Line 41  contains
41    
42      ! Local:      ! Local:
43      integer ncum      integer ncum
44      integer i, j, il, num1      integer i, il, imax
45      real tinv, delti      real tinv, delti
46      real awat, afac, afac1, afac2, bfac      real afac, afac1, afac2, bfac
47      real pr1, pr2, sigt, b6, c6, revap, tevap, delth      real pr1, pr2, sigt, b6, c6, revap, tevap, delth
48      real amfac, amp2, xf, tf, fac2, ur, sru, fac, d, af, bf      real amfac, amp2, xf, tf, fac2, ur, sru, fac, d, af, bf
49      real ampmax      real ampmax
50      real lvcp(klon, klev)      real lvcp(klon, klev)
51      real wdtrain(size(icb))      real wdtrain(size(icb)) ! (ncum)
52      logical lwork(size(icb))      logical lwork(size(icb)) ! (ncum)
53    
54      !------------------------------------------------------      !------------------------------------------------------
55    
# Line 65  contains Line 71  contains
71         enddo         enddo
72      enddo      enddo
73    
74      ! check whether ep(inb) = 0, if so, skip precipitating      ! Check whether ep(inb) = 0. If so, skip precipitating downdraft
75      ! downdraft calculation      ! calculation.
76    
77      forall (il = 1:ncum) lwork(il) = ep(il, inb(il)) >= 1e-4      forall (il = 1:ncum) lwork(il) = ep(il, inb(il)) >= 1e-4
78    
79      wdtrain = 0.      imax = nl - 1
80        do while (.not. any(inb >= imax .and. lwork) .and. imax >= 1)
81           imax = imax - 1
82        end do
83    
84        downdraft_loop: DO i = imax, 1, - 1
85           ! Integrate liquid water equation to find condensed water
86           ! and condensed water flux
87    
88           ! Calculate detrained precipitation
89           forall (il = 1:ncum, inb(il) >= i .and. lwork(il)) wdtrain(il) = grav &
90                * (ep(il, i) * m(il, i) * clw(il, i) &
91                + sum(max(elij(il, :i - 1, i) - (1. - ep(il, i)) * clw(il, i), 0.) &
92                * ment(il, :i - 1, i)))
93    
94      downdraft_loop: DO i = nl - 1, 1, - 1         ! Find rain water and evaporation using provisional
95         num1 = 0         ! estimates of qp(i) and qp(i - 1)
96    
97         do il = 1, ncum         do il = 1, ncum
98            if (i <= inb(il) .and. lwork(il)) num1 = num1 + 1            if (i <= inb(il) .and. lwork(il)) then
99         enddo               wt(il, i) = 45.
100    
101         if (num1 > 0) then               if (i < inb(il)) then
102            ! integrate liquid water equation to find condensed water                  qp(il, i) = qp(il, i + 1) + (cpd * (t(il, i + 1) - t(il, i)) &
103            ! and condensed water flux                       + gz(il, i + 1) - gz(il, i)) / lv(il, i)
104                    qp(il, i) = 0.5 * (qp(il, i) + q(il, i))
           ! calculate detrained precipitation  
   
           do il = 1, ncum  
              if (i <= inb(il) .and. lwork(il)) then  
                 wdtrain(il) = grav * ep(il, i) * m(il, i) * clw(il, i)  
105               endif               endif
           enddo  
106    
107            if (i > 1) then               qp(il, i) = max(qp(il, i), 0.)
108               do j = 1, i - 1               qp(il, i) = min(qp(il, i), qs(il, i))
109                  do il = 1, ncum               qp(il, inb(il)) = q(il, inb(il))
110                     if (i <= inb(il) .and. lwork(il)) then  
111                        awat = elij(il, j, i) - (1. - ep(il, i)) * clw(il, i)               if (i == 1) then
112                        awat = max(awat, 0.)                  afac = p(il, 1) * (qs(il, 1) - qp(il, 1)) &
113                        wdtrain(il) = wdtrain(il) + grav * awat * ment(il, j, i)                       / (1e4 + 2000. * p(il, 1) * qs(il, 1))
114                     endif               else
115                  enddo                  qp(il, i - 1) = qp(il, i) + (cpd * (t(il, i) - t(il, i - 1)) &
116               end do                       + gz(il, i) - gz(il, i - 1)) / lv(il, i)
117            endif                  qp(il, i - 1) = 0.5 * (qp(il, i - 1) + q(il, i - 1))
118                    qp(il, i - 1) = min(qp(il, i - 1), qs(il, i - 1))
119            ! find rain water and evaporation using provisional                  qp(il, i - 1) = max(qp(il, i - 1), 0.)
120            ! estimates of qp(i) and qp(i - 1)                  afac1 = p(il, i) * (qs(il, i) - qp(il, i)) &
121                         / (1e4 + 2000. * p(il, i) * qs(il, i))
122                    afac2 = p(il, i - 1) * (qs(il, i - 1) - qp(il, i - 1)) &
123                         / (1e4 + 2000. * p(il, i - 1) * qs(il, i - 1))
124                    afac = 0.5 * (afac1 + afac2)
125                 endif
126    
127            do il = 1, ncum               if (i == inb(il)) afac = 0.
128               if (i <= inb(il) .and. lwork(il)) then               afac = max(afac, 0.)
129                  wt(il, i) = 45.               bfac = 1. / (sigd * wt(il, i))
130    
131                  if (i < inb(il)) then               ! Prise en compte de la variation progressive de sigt dans
132                     qp(il, i) = qp(il, i + 1) + (cpd * (t(il, i + 1) &               ! les couches icb et icb - 1:
133                          - t(il, i)) + gz(il, i + 1) - gz(il, i)) / lv(il, i)               ! pour plcl < ph(i + 1), pr1 = 0 et pr2 = 1
134                     qp(il, i) = 0.5 * (qp(il, i) + q(il, i))               ! pour plcl > ph(i), pr1 = 1 et pr2 = 0
135                  endif               ! pour ph(i + 1) < plcl < ph(i), pr1 est la proportion \`a cheval
136                 ! sur le nuage, et pr2 est la proportion sous la base du
137                 ! nuage.
138                 pr1 = (plcl(il) - ph(il, i + 1)) / (ph(il, i) - ph(il, i + 1))
139                 pr1 = max(0., min(1., pr1))
140                 pr2 = (ph(il, i) - plcl(il)) / (ph(il, i) - ph(il, i + 1))
141                 pr2 = max(0., min(1., pr2))
142                 sigt = sigp(il, i) * pr1 + pr2
143    
144                 b6 = bfac * 50. * sigd * (ph(il, i) - ph(il, i + 1)) * sigt * afac
145                 c6 = water(il, i + 1) + bfac * wdtrain(il) - 50. * sigd * bfac &
146                      * (ph(il, i) - ph(il, i + 1)) * evap(il, i + 1)
147                 if (c6 > 0.) then
148                    revap = 0.5 * (- b6 + sqrt(b6 * b6 + 4. * c6))
149                    evap(il, i) = sigt * afac * revap
150                    water(il, i) = revap * revap
151                 else
152                    evap(il, i) = - evap(il, i + 1) + 0.02 * (wdtrain(il) + sigd &
153                         * wt(il, i) * water(il, i + 1)) / (sigd * (ph(il, i) &
154                         - ph(il, i + 1)))
155                 end if
156    
157                 ! Calculate precipitating downdraft mass flux under
158                 ! hydrostatic approximation
159    
160                 test_above_surface: if (i /= 1) then
161                    tevap = max(0., evap(il, i))
162                    delth = max(0.001, (th(il, i) - th(il, i - 1)))
163                    mp(il, i) = 100. * ginv * lvcp(il, i) * sigd * tevap &
164                         * (p(il, i - 1) - p(il, i)) / delth
165    
166                    ! If hydrostatic assumption fails, solve cubic
167                    ! difference equation for downdraft theta and mass
168                    ! flux from two simultaneous differential equations
169    
170                    amfac = sigd * sigd * 70. * ph(il, i) &
171                         * (p(il, i - 1) - p(il, i)) &
172                         * (th(il, i) - th(il, i - 1)) / (tv(il, i) * th(il, i))
173                    amp2 = abs(mp(il, i + 1) * mp(il, i + 1) - mp(il, i) &
174                         * mp(il, i))
175    
176                    if (amp2 > 0.1 * amfac) then
177                       xf = 100. * sigd * sigd * sigd * (ph(il, i) - ph(il, i + 1))
178                       tf = b(il, i) - 5. * (th(il, i) - th(il, i - 1)) &
179                            * t(il, i) / (lvcp(il, i) * sigd * th(il, i))
180                       af = xf * tf + mp(il, i + 1) * mp(il, i + 1) * tinv
181                       bf = 2. * (tinv * mp(il, i + 1))**3 + tinv &
182                            * mp(il, i + 1) * xf * tf + 50. * (p(il, i - 1) &
183                            - p(il, i)) * xf * tevap
184                       fac2 = 1.
185                       if (bf < 0.) fac2 = - 1.
186                       bf = abs(bf)
187                       ur = 0.25 * bf * bf - af * af * af * tinv * tinv * tinv
188    
189                       if (ur >= 0.) then
190                          sru = sqrt(ur)
191                          fac = 1.
192                          if ((0.5 * bf - sru) < 0.) fac = - 1.
193                          mp(il, i) = mp(il, i + 1) * tinv + (0.5 * bf &
194                               + sru)**tinv + fac * (abs(0.5 * bf - sru))**tinv
195                       else
196                          d = atan(2. * sqrt(- ur) / (bf + 1e-28))
197                          if (fac2 < 0.)d = 3.14159 - d
198                          mp(il, i) = mp(il, i + 1) * tinv + 2. * sqrt(af * tinv) &
199                               * cos(d * tinv)
200                       endif
201    
202                  qp(il, i) = max(qp(il, i), 0.)                     mp(il, i) = max(0., mp(il, i))
                 qp(il, i) = min(qp(il, i), qs(il, i))  
                 qp(il, inb(il)) = q(il, inb(il))  
203    
204                  if (i == 1) then                     ! Il y a vraisemblablement une erreur dans la
205                     afac = p(il, 1) * (qs(il, 1) - qp(il, 1)) &                     ! ligne suivante : il faut diviser par (mp(il,
206                          / (1e4 + 2000. * p(il, 1) * qs(il, 1))                     ! i) * sigd * grav) et non par (mp(il, i) + sigd
207                  else                     ! * 0.1).  Et il faut bien revoir les facteurs
208                     qp(il, i - 1) = qp(il, i) + (cpd * (t(il, i) &                     ! 100.
209                          - t(il, i - 1)) + gz(il, i) - gz(il, i - 1)) / lv(il, i)                     b(il, i - 1) = b(il, i) + 100. * (p(il, i - 1) - p(il, i)) &
210                     qp(il, i - 1) = 0.5 * (qp(il, i - 1) + q(il, i - 1))                          * tevap / (mp(il, i) + sigd * 0.1) - 10. * (th(il, i) &
211                     qp(il, i - 1) = min(qp(il, i - 1), qs(il, i - 1))                          - th(il, i - 1)) * t(il, i) / (lvcp(il, i) * sigd &
212                     qp(il, i - 1) = max(qp(il, i - 1), 0.)                          * th(il, i))
213                     afac1 = p(il, i) * (qs(il, i) - qp(il, i)) &                     b(il, i - 1) = max(b(il, i - 1), 0.)
                         / (1e4 + 2000. * p(il, i) * qs(il, i))  
                    afac2 = p(il, i - 1) * (qs(il, i - 1) - qp(il, i - 1)) &  
                         / (1e4 + 2000. * p(il, i - 1) * qs(il, i - 1))  
                    afac = 0.5 * (afac1 + afac2)  
214                  endif                  endif
215    
216                  if (i == inb(il)) afac = 0.                  ! Limit magnitude of mp(i) to meet CFL condition:
217                  afac = max(afac, 0.)                  ampmax = 2. * (ph(il, i) - ph(il, i + 1)) * delti
218                  bfac = 1. / (sigd * wt(il, i))                  amp2 = 2. * (ph(il, i - 1) - ph(il, i)) * delti
219                    ampmax = min(ampmax, amp2)
220                  ! prise en compte de la variation progressive de sigt dans                  mp(il, i) = min(mp(il, i), ampmax)
221                  ! les couches icb et icb - 1:  
222                  ! pour plcl < ph(i + 1), pr1 = 0 & pr2 = 1                  ! Force mp to decrease linearly to zero between cloud
223                  ! pour plcl > ph(i), pr1 = 1 & pr2 = 0                  ! base and the surface:
224                  ! pour ph(i + 1) < plcl < ph(i), pr1 est la proportion a cheval                  if (p(il, i) > p(il, icb(il))) mp(il, i) = mp(il, icb(il)) &
225                  ! sur le nuage, et pr2 est la proportion sous la base du                       * (p(il, 1) - p(il, i)) / (p(il, 1) - p(il, icb(il)))
226                  ! nuage.               endif test_above_surface
227                  pr1 = (plcl(il) - ph(il, i + 1)) / (ph(il, i) - ph(il, i + 1))  
228                  pr1 = max(0., min(1., pr1))               ! Find mixing ratio of precipitating downdraft
229                  pr2 = (ph(il, i) - plcl(il)) / (ph(il, i) - ph(il, i + 1))  
230                  pr2 = max(0., min(1., pr2))               if (i /= inb(il)) then
231                  sigt = sigp(il, i) * pr1 + pr2                  qp(il, i) = q(il, i)
232    
233                  b6 = bfac * 50. * sigd * (ph(il, i) - ph(il, i + 1)) * sigt &                  if (mp(il, i) > mp(il, i + 1)) then
234                       * afac                     qp(il, i) = qp(il, i + 1) * mp(il, i + 1) + q(il, i) &
235                  c6 = water(il, i + 1) + bfac * wdtrain(il) - 50. * sigd * bfac &                          * (mp(il, i) - mp(il, i + 1)) + 100. * ginv * 0.5 &
236                       * (ph(il, i) - ph(il, i + 1)) * evap(il, i + 1)                          * sigd * (ph(il, i) - ph(il, i + 1)) &
237                  if (c6 > 0.) then                          * (evap(il, i + 1) + evap(il, i))
238                     revap = 0.5 * (- b6 + sqrt(b6 * b6 + 4. * c6))                     qp(il, i) = qp(il, i) / mp(il, i)
239                     evap(il, i) = sigt * afac * revap                     up(il, i) = up(il, i + 1) * mp(il, i + 1) + u(il, i) &
240                     water(il, i) = revap * revap                          * (mp(il, i) - mp(il, i + 1))
241                       up(il, i) = up(il, i) / mp(il, i)
242                       vp(il, i) = vp(il, i + 1) * mp(il, i + 1) + v(il, i) &
243                            * (mp(il, i) - mp(il, i + 1))
244                       vp(il, i) = vp(il, i) / mp(il, i)
245                  else                  else
246                     evap(il, i) = - evap(il, i + 1) + 0.02 * (wdtrain(il) &                     if (mp(il, i + 1) > 1e-16) then
247                          + sigd * wt(il, i) * water(il, i + 1)) &                        qp(il, i) = qp(il, i + 1) + 100. * ginv * 0.5 * sigd &
248                          / (sigd * (ph(il, i) - ph(il, i + 1)))                             * (ph(il, i) - ph(il, i + 1)) * (evap(il, i + 1) &
249                  end if                             + evap(il, i)) / mp(il, i + 1)
250                          up(il, i) = up(il, i + 1)
251                  ! calculate precipitating downdraft mass flux under                        vp(il, i) = vp(il, i + 1)
                 ! hydrostatic approximation  
   
                 if (i /= 1) then  
                    tevap = max(0., evap(il, i))  
                    delth = max(0.001, (th(il, i) - th(il, i - 1)))  
                    mp(il, i) = 100. * ginv * lvcp(il, i) * sigd * tevap &  
                         * (p(il, i - 1) - p(il, i)) / delth  
   
                    ! If hydrostatic assumption fails, solve cubic  
                    ! difference equation for downdraft theta and mass  
                    ! flux from two simultaneous differential equations  
   
                    amfac = sigd * sigd * 70. * ph(il, i) &  
                         * (p(il, i - 1) - p(il, i)) &  
                         * (th(il, i) - th(il, i - 1)) / (tv(il, i) * th(il, i))  
                    amp2 = abs(mp(il, i + 1) * mp(il, i + 1) - mp(il, i) &  
                         * mp(il, i))  
   
                    if (amp2 > 0.1 * amfac) then  
                       xf = 100. * sigd * sigd * sigd * (ph(il, i) &  
                            - ph(il, i + 1))  
                       tf = b(il, i) - 5. * (th(il, i) - th(il, i - 1)) &  
                            * t(il, i) / (lvcp(il, i) * sigd * th(il, i))  
                       af = xf * tf + mp(il, i + 1) * mp(il, i + 1) * tinv  
                       bf = 2. * (tinv * mp(il, i + 1))**3 + tinv &  
                            * mp(il, i + 1) * xf * tf + 50. * (p(il, i - 1) &  
                            - p(il, i)) * xf * tevap  
                       fac2 = 1.  
                       if (bf < 0.) fac2 = - 1.  
                       bf = abs(bf)  
                       ur = 0.25 * bf * bf - af * af * af * tinv * tinv * tinv  
   
                       if (ur >= 0.) then  
                          sru = sqrt(ur)  
                          fac = 1.  
                          if ((0.5 * bf - sru) < 0.) fac = - 1.  
                          mp(il, i) = mp(il, i + 1) * tinv &  
                               + (0.5 * bf + sru)**tinv &  
                               + fac * (abs(0.5 * bf - sru))**tinv  
                       else  
                          d = atan(2. * sqrt(- ur) / (bf + 1e-28))  
                          if (fac2 < 0.)d = 3.14159 - d  
                          mp(il, i) = mp(il, i + 1) * tinv + 2. &  
                               * sqrt(af * tinv) * cos(d * tinv)  
                       endif  
   
                       mp(il, i) = max(0., mp(il, i))  
   
                       ! Il y a vraisemblablement une erreur dans la  
                       ! ligne suivante : il faut diviser par (mp(il,  
                       ! i) * sigd * grav) et non par (mp(il, i) + sigd  
                       ! * 0.1).  Et il faut bien revoir les facteurs  
                       ! 100.  
                       b(il, i - 1) = b(il, i) + 100. * (p(il, i - 1) &  
                            - p(il, i)) * tevap / (mp(il, i) + sigd * 0.1) &  
                            - 10. * (th(il, i) - th(il, i - 1)) * t(il, i) &  
                            / (lvcp(il, i) * sigd * th(il, i))  
                       b(il, i - 1) = max(b(il, i - 1), 0.)  
                    endif  
   
                    ! limit magnitude of mp(i) to meet cfl condition  
                    ampmax = 2. * (ph(il, i) - ph(il, i + 1)) * delti  
                    amp2 = 2. * (ph(il, i - 1) - ph(il, i)) * delti  
                    ampmax = min(ampmax, amp2)  
                    mp(il, i) = min(mp(il, i), ampmax)  
   
                    ! force mp to decrease linearly to zero  
                    ! between cloud base and the surface  
                    if (p(il, i) > p(il, icb(il))) mp(il, i) = mp(il, icb(il)) &  
                         * (p(il, 1) - p(il, i)) / (p(il, 1) - p(il, icb(il)))  
                 endif ! i == 1  
   
                 ! find mixing ratio of precipitating downdraft  
   
                 if (i /= inb(il)) then  
                    qp(il, i) = q(il, i)  
   
                    if (mp(il, i) > mp(il, i + 1)) then  
                       qp(il, i) = qp(il, i + 1) * mp(il, i + 1) + q(il, i) &  
                            * (mp(il, i) - mp(il, i + 1)) + 100. * ginv &  
                            * 0.5 * sigd * (ph(il, i) - ph(il, i + 1)) &  
                            * (evap(il, i + 1) + evap(il, i))  
                       qp(il, i) = qp(il, i) / mp(il, i)  
                       up(il, i) = up(il, i + 1) * mp(il, i + 1) + u(il, i) &  
                            * (mp(il, i) - mp(il, i + 1))  
                       up(il, i) = up(il, i) / mp(il, i)  
                       vp(il, i) = vp(il, i + 1) * mp(il, i + 1) + v(il, i) &  
                            * (mp(il, i) - mp(il, i + 1))  
                       vp(il, i) = vp(il, i) / mp(il, i)  
                    else  
                       if (mp(il, i + 1) > 1e-16) then  
                          qp(il, i) = qp(il, i + 1) + 100. * ginv * 0.5 * sigd &  
                               * (ph(il, i) - ph(il, i + 1)) &  
                               * (evap(il, i + 1) + evap(il, i)) / mp(il, i + 1)  
                          up(il, i) = up(il, i + 1)  
                          vp(il, i) = vp(il, i + 1)  
                       endif  
252                     endif                     endif
   
                    qp(il, i) = min(qp(il, i), qs(il, i))  
                    qp(il, i) = max(qp(il, i), 0.)  
253                  endif                  endif
254    
255                    qp(il, i) = min(qp(il, i), qs(il, i))
256                    qp(il, i) = max(qp(il, i), 0.)
257               endif               endif
258            end do            endif
259         end if         end do
260      end DO downdraft_loop      end DO downdraft_loop
261    
262    end SUBROUTINE cv30_unsat    end SUBROUTINE cv30_unsat

Legend:
Removed from v.189  
changed lines
  Added in v.194

  ViewVC Help
Powered by ViewVC 1.1.21