source: trunk/LMDZ.GENERIC/libf/phystd/thermcell_height.F90 @ 2176

Last change on this file since 2176 was 2143, checked in by aboissinot, 5 years ago

Update the thermal plume model:

  • check formulae consistency between thermcell_plume and thercell_closure
  • compute correctly thermal plume height
  • fix alimentation computation in the first unstable layer
File size: 7.8 KB
RevLine 
[2060]1!
2!
3!
[2143]4SUBROUTINE thermcell_height(ngrid,nlay,lmin,linter,lmix,lmax,zw2,             &
5                            zlev,zmin,zmix,zmax,wmax,f_star)
[2060]6     
7     
[2127]8!===============================================================================
9!  Purpose: calcul des caracteristiques du thermique: zmax,wmax,zmix
10!===============================================================================
[2060]11     
12      IMPLICIT NONE
13     
14     
[2127]15!===============================================================================
[2060]16! Declaration
[2127]17!===============================================================================
[2060]18     
[2127]19!     Inputs:
20!     -------
[2060]21     
[2127]22      INTEGER ngrid, nlay
[2060]23      INTEGER lmin(ngrid)
24     
25      REAL zlev(ngrid,nlay+1)
26      REAL f_star(ngrid,nlay+1)
27     
[2127]28!     Outputs:
29!     --------
[2060]30     
31      INTEGER lmix(ngrid)
32      INTEGER lmax(ngrid)
33     
34      REAL linter(ngrid)
[2143]35      REAL zmin(ngrid)                          ! Altitude of the plume bottom
36      REAL zmax(ngrid)                          ! Altitude of the plume top
37      REAL zmix(ngrid)                          ! Altitude of maximal vertical speed
38      REAL wmax(ngrid)                          ! Maximal vertical speed
39      REAL zw2(ngrid,nlay+1)                    ! Square vertical speed (becomes its square root)
[2060]40     
[2127]41!     Local:
42!     ------
[2060]43     
[2127]44      INTEGER ig, l
[2060]45     
46      REAL zlevinter(ngrid)
47     
[2127]48!===============================================================================
[2060]49! Initialization
[2127]50!===============================================================================
[2060]51     
52      DO ig=1,ngrid
[2127]53         lmax(ig) = lmin(ig)
[2060]54         lmix(ig) = lmin(ig)
55      ENDDO
56     
57      DO ig=1,ngrid
58         wmax(ig) = 0.
59      ENDDO
60     
61      DO ig=1,ngrid
62         zmax(ig) = 0.
63         zlevinter(ig) = zlev(ig,1)
64      ENDDO
65     
[2127]66!===============================================================================
[2143]67! Thermal plume height
[2127]68!===============================================================================
[2060]69     
[2127]70!-------------------------------------------------------------------------------
[2143]71! Calcul de zmin
72!-------------------------------------------------------------------------------
73     
74      DO l=1,nlay
75         DO ig=1,ngrid
76            zmin(ig) = zlev(ig,lmin(ig))
77         ENDDO
78      ENDDO
79     
80!-------------------------------------------------------------------------------
[2060]81! Calcul de lmax
[2127]82!-------------------------------------------------------------------------------
[2060]83     
84      DO ig=1,ngrid
85         DO l=nlay,lmin(ig)+1,-1
[2143]86            IF ((zw2(ig,l) <= 0.).or.(f_star(ig,l) <= 0.)) THEN
[2060]87               lmax(ig) = l - 1
88            ENDIF
89         ENDDO
90      ENDDO
91     
[2127]92!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[2143]93! AB: Problematic case where thermal plume reaches the top of the model...
[2127]94!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[2060]95      DO ig=1,ngrid
[2143]96         IF (zw2(ig,nlay) > 0.) THEN
[2127]97            print *, 'WARNING: a thermal plume reaches the highest layer!'
98            print *, 'ig,l', ig, nlay
99            print *, 'zw2', zw2(ig,nlay)
100            lmax(ig) = nlay
[2060]101         ENDIF
102      ENDDO
103     
[2127]104!-------------------------------------------------------------------------------
[2060]105! Calcul de zmax continu via le linter
[2127]106!-------------------------------------------------------------------------------
[2060]107     
[2127]108!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[2060]109! AB : lmin=lmax means the plume is not active and then zw2=0 at each level.
110!      Otherwise we have lmax>lmin.
[2127]111!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[2060]112      DO ig=1,ngrid
113         l = lmax(ig)
[2143]114         IF (l == lmin(ig)) THEN
[2060]115            linter(ig) = l
116         ELSE
117            linter(ig) = l - zw2(ig,l) / (zw2(ig,l+1) - zw2(ig,l))
118         ENDIF
119      ENDDO
120     
[2127]121      DO ig=1,ngrid
[2143]122         zlevinter(ig) = zlev(ig,lmax(ig)) + (linter(ig) - lmax(ig))          &
123         &             * (zlev(ig,lmax(ig)+1) - zlev(ig,lmax(ig)))
124         zmax(ig) = max(zmax(ig), zlevinter(ig))
[2060]125      ENDDO
126     
[2127]127!===============================================================================
[2143]128! Thermal plume maximal speed and inversion layer
[2127]129!===============================================================================
[2060]130     
[2127]131!-------------------------------------------------------------------------------
[2060]132! Calcul de lmix et wmax
[2127]133!-------------------------------------------------------------------------------
[2060]134     
135      DO l=1,nlay
136         DO ig=1,ngrid
[2143]137            IF((l <= lmax(ig)).and.(l > lmin(ig))) THEN
[2060]138               IF (zw2(ig,l).lt.0.) THEN
139                  print *, 'ERROR: zw2 has negative value(s)!'
[2127]140                  print *, 'ig,l', ig, l
141                  print *, 'zw2', zw2(ig,l)
[2060]142                  CALL abort
143               ENDIF
144               
[2127]145!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[2060]146! AB : WARNING zw2 becomes its square root!
[2127]147!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[2060]148               zw2(ig,l) = sqrt(zw2(ig,l))
149               
[2143]150               IF (zw2(ig,l) > wmax(ig)) THEN
[2060]151                  wmax(ig)  = zw2(ig,l)
152                  lmix(ig)  = l
153               ENDIF
154            ELSE
155               zw2(ig,l) = 0.
156            ENDIF
157         ENDDO
158      ENDDO
159     
[2127]160!-------------------------------------------------------------------------------
[2060]161! Calcul de zmix continu (profil parabolique des vitesses)
[2127]162!-------------------------------------------------------------------------------
[2060]163     
164      DO ig=1,ngrid
[2143]165         IF (lmix(ig) > lmin(ig)) THEN
[2060]166            IF (((zw2(ig,lmix(ig)-1)-zw2(ig,lmix(ig)))                        &
167            &        *((zlev(ig,lmix(ig)))-(zlev(ig,lmix(ig)+1)))             &
168            &        -(zw2(ig,lmix(ig))-zw2(ig,lmix(ig)+1))                   &
[2143]169            &        *((zlev(ig,lmix(ig)-1))-(zlev(ig,lmix(ig))))) > 1e-10)   &
[2060]170            &        THEN
171               zmix(ig) = ((zw2(ig,lmix(ig)-1)-zw2(ig,lmix(ig)))              &
172               &        *((zlev(ig,lmix(ig)))**2-(zlev(ig,lmix(ig)+1))**2)    &
173               &        -(zw2(ig,lmix(ig))-zw2(ig,lmix(ig)+1))                &
174               &        *((zlev(ig,lmix(ig)-1))**2-(zlev(ig,lmix(ig)))**2))   &
175               &        /(2.*((zw2(ig,lmix(ig)-1)-zw2(ig,lmix(ig)))           &
176               &        *((zlev(ig,lmix(ig)))-(zlev(ig,lmix(ig)+1)))          &
177               &        -(zw2(ig,lmix(ig))-zw2(ig,lmix(ig)+1))                &
[2143]178               &        *((zlev(ig,lmix(ig)-1))-(zlev(ig,lmix(ig))))))
[2060]179            ELSE
[2143]180               zmix(ig) = zlev(ig,lmix(ig))
[2127]181               print *, 'WARNING: problematic zmix value!'
[2060]182            ENDIF
183         ELSE
184            zmix(ig) = 0.
185         ENDIF
186      ENDDO
187     
[2127]188!===============================================================================
[2143]189! Check consistence between zmax and zmix
[2127]190!===============================================================================
[2060]191     
[2143]192!-------------------------------------------------------------------------------
193!
194!-------------------------------------------------------------------------------
195     
[2060]196      DO ig=1,ngrid
[2143]197         IF ((zmax(ig)-zmix(ig)) < 0.) THEN
198            print *, 'WARNING: we have zmix > zmax!'
199            print *, 'zmax,zmix_old,zmix_new', zmax(ig), zmix(ig), 0.9 * zmax(ig)
[2060]200            zmix(ig) = 0.9 * zmax(ig)
201         ENDIF
202      ENDDO
203     
[2127]204!-------------------------------------------------------------------------------
[2060]205! Calcul du nouveau lmix correspondant
[2127]206!-------------------------------------------------------------------------------
[2060]207     
208      DO ig=1,ngrid
209         DO l=1,nlay
[2143]210            IF ((zmix(ig) >= zlev(ig,l)).and.(zmix(ig) < zlev(ig,l+1))) THEN
[2127]211               lmix(ig) = l
[2060]212            ENDIF
213         ENDDO
214      ENDDO
215     
216     
217RETURN
218END
Note: See TracBrowser for help on using the repository browser.