source: trunk/LMDZ.GENERIC/libf/phystd/convadj.F @ 146

Last change on this file since 146 was 135, checked in by aslmd, 14 years ago

CHANGEMENT ARBORESCENCE ETAPE 2 -- NON COMPLET

File size: 9.6 KB
Line 
1      SUBROUTINE convadj(ngrid,nlay,nq,ptimestep,
2     S                   pplay,pplev,ppopsk,
3     $                   pu,pv,ph,pq,
4     $                   pdufi,pdvfi,pdhfi,pdqfi,
5     $                   pduadj,pdvadj,pdhadj,
6     $                   pdqadj)
7      IMPLICIT NONE
8
9c=======================================================================
10c
11c   ajustement convectif sec
12c   on ajoute les tendances pdhfi au profil pdh avant l'ajustement
13c   SPECIAL VERSION : if one tracer is CO2, take into account the
14c   Molecular mass variation (e.g. when CO2 condense) to trigger
15c   convection  F. Forget 01/2005
16c
17c=======================================================================
18
19c-----------------------------------------------------------------------
20c   declarations:
21c   -------------
22
23#include "dimensions.h"
24#include "dimphys.h"
25#include "comcstfi.h"
26#include "callkeys.h"
27#include "tracer.h"
28
29
30c   arguments:
31c   ----------
32
33      INTEGER ngrid,nlay
34      REAL ptimestep
35      REAL ph(ngrid,nlay),pdhfi(ngrid,nlay),pdhadj(ngrid,nlay)
36      REAL pplay(ngrid,nlay),pplev(ngrid,nlay+1),ppopsk(ngrid,nlay)
37      REAL pu(ngrid,nlay),pdufi(ngrid,nlay),pduadj(ngrid,nlay)
38      REAL pv(ngrid,nlay),pdvfi(ngrid,nlay),pdvadj(ngrid,nlay)
39
40c    Traceurs :
41      integer nq
42      real pq(ngrid,nlay,nq), pdqfi(ngrid,nlay,nq)
43      real pdqadj(ngrid,nlay,nq)
44
45
46c   local:
47c   ------
48
49      INTEGER ig,i,l,l1,l2,jj
50      INTEGER jcnt, jadrs(ngridmx)
51
52      REAL sig(nlayermx+1),sdsig(nlayermx),dsig(nlayermx)
53      REAL zu(ngridmx,nlayermx),zv(ngridmx,nlayermx)
54      REAL zh(ngridmx,nlayermx)
55      REAL zu2(ngridmx,nlayermx),zv2(ngridmx,nlayermx)
56      REAL zh2(ngridmx,nlayermx), zhc(ngridmx,nlayermx)
57      REAL zhm,zsm,zdsm,zum,zvm,zalpha,zhmc
58     
59
60c    Traceurs :
61      INTEGER iq,ico2
62      save ico2
63      REAL zq(ngridmx,nlayermx,nqmx), zq2(ngridmx,nlayermx,nqmx)
64      REAL zqm(nqmx),zqco2m
65      real m_co2, m_noco2, A , B
66      save A, B
67c    Temporaire (for diagnostic)
68c      REAL diag_alpha(ngridmx)
69
70      real mtot1, mtot2 , mm1, mm2
71       integer l1ref, l2ref
72      LOGICAL vtest(ngridmx),down,firstcall
73      save firstcall
74      data firstcall/.true./
75
76      EXTERNAL SCOPY
77c
78c-----------------------------------------------------------------------
79c   initialisation:
80c   ---------------
81c
82      IF (firstcall) THEN
83        IF(ngrid.NE.ngridmx) THEN
84           PRINT*
85           PRINT*,'STOP dans convadj'
86           PRINT*,'ngrid    =',ngrid
87           PRINT*,'ngridmx  =',ngridmx
88        ENDIF
89        ico2=0
90        if (tracer) then
91c          Prepare Special treatment if one of the tracer is CO2 gas
92           do iq=1,nqmx
93             if (noms(iq).eq."co2") then
94                print*,'dont go there'
95                stop
96                ico2=iq
97                m_co2 = 44.01E-3  ! CO2 molecular mass (kg/mol)   
98                m_noco2 = 33.37E-3  ! Non condensible mol mass (kg/mol)   
99c               Compute A and B coefficient use to compute
100c               mean molecular mass Mair defined by
101c               1/Mair = q(ico2)/m_co2 + (1-q(ico2))/m_noco2
102c               1/Mair = A*q(ico2) + B
103                A =(1/m_co2 - 1/m_noco2)
104                B=1/m_noco2
105             end if
106           enddo
107        endif
108        firstcall=.false.
109      ENDIF ! of IF (firstcall)
110
111c
112c-----------------------------------------------------------------------
113c   detection des profils a modifier:
114c   ---------------------------------
115c   si le profil est a modifier
116c   (i.e. ph(niv_sup) < ph(niv_inf) )
117c   alors le tableau "vtest" est mis a .TRUE. ;
118c   sinon, il reste a sa valeur initiale (.FALSE.)
119c   cette operation est vectorisable
120c   On en profite pour copier la valeur initiale de "ph"
121c   dans le champ de travail "zh"
122
123
124      DO l=1,nlay
125         DO ig=1,ngrid
126            zh(ig,l)=ph(ig,l)+pdhfi(ig,l)*ptimestep
127            zu(ig,l)=pu(ig,l)+pdufi(ig,l)*ptimestep
128            zv(ig,l)=pv(ig,l)+pdvfi(ig,l)*ptimestep
129         ENDDO
130      ENDDO
131
132      if(tracer) then     
133        DO iq =1, nq
134         DO l=1,nlay
135           DO ig=1,ngrid
136              zq(ig,l,iq)=pq(ig,l,iq)+pdqfi(ig,l,iq)*ptimestep
137           ENDDO
138         ENDDO
139        ENDDO
140      end if
141
142
143      CALL scopy(ngrid*nlay,zh,1,zh2,1)
144      CALL scopy(ngrid*nlay,zu,1,zu2,1)
145      CALL scopy(ngrid*nlay,zv,1,zv2,1)
146      CALL scopy(ngrid*nlay*nq,zq,1,zq2,1)
147
148      DO ig=1,ngrid
149        vtest(ig)=.FALSE.
150      ENDDO
151c
152      if (ico2.ne.0) then
153c        Special case if one of the tracer is CO2 gas
154         DO l=1,nlay
155           DO ig=1,ngrid
156             zhc(ig,l) = zh2(ig,l)*(A*zq2(ig,l,ico2)+B)
157           ENDDO
158         ENDDO
159       else
160          CALL scopy(ngrid*nlay,zh2,1,zhc,1)
161       end if
162
163       
164
165      DO l=2,nlay
166        DO ig=1,ngrid
167          IF(zhc(ig,l).LT.zhc(ig,l-1)) vtest(ig)=.TRUE.
168        ENDDO
169      ENDDO
170c
171      jcnt=0
172      DO ig=1,ngrid
173         IF(vtest(ig)) THEN
174            jcnt=jcnt+1
175            jadrs(jcnt)=ig
176         ENDIF
177      ENDDO
178
179
180c-----------------------------------------------------------------------
181c  Ajustement des "jcnt" profils instables indices par "jadrs":
182c  ------------------------------------------------------------
183c
184      DO jj = 1, jcnt   ! loop on every convective grid point
185c
186          i = jadrs(jj)
187 
188c   Calcul des niveaux sigma sur cette colonne
189          DO l=1,nlay+1
190            sig(l)=pplev(i,l)/pplev(i,1)
191       
192          ENDDO
193         DO l=1,nlay
194            dsig(l)=sig(l)-sig(l+1)
195            sdsig(l)=ppopsk(i,l)*dsig(l)
196         ENDDO
197          l2 = 1
198c
199c      -- boucle de sondage vers le haut
200c
201cins$     Loop  vers le haut sur l2
202          DO
203c
204            l2 = l2 + 1
205            IF (l2 .GT. nlay) EXIT
206            IF (zhc(i, l2) .LT. zhc(i, l2-1)) THEN
207 
208c          -- l2 est le niveau le plus haut de la colonne instable
209 
210              l1 = l2 - 1
211              l  = l1
212              zsm = sdsig(l2)
213              zdsm = dsig(l2)
214              zhm = zh2(i, l2)
215              if(ico2.ne.0) zqco2m = zq2(i,l2,ico2)
216c
217c          -- boucle de sondage vers le bas
218c             Loop
219              DO
220c
221                zsm = zsm + sdsig(l)
222                zdsm = zdsm + dsig(l)
223                zhm = zhm + sdsig(l) * (zh2(i, l) - zhm) / zsm
224                if(ico2.ne.0) then
225                  zqco2m =
226     &            zqco2m + dsig(l) * (zq2(i,l,ico2) - zqco2m) / zdsm
227                  zhmc = zhm*(A*zqco2m+B)
228                else
229                  zhmc = zhm
230                end if
231 
232c            -- doit on etendre la colonne vers le bas ?
233 
234                down = .FALSE.
235                IF (l1 .NE. 1) THEN    !--  and then
236                  IF (zhmc .LT. zhc(i, l1-1)) THEN
237                    down = .TRUE.
238                  END IF
239                END IF
240 
241                IF (down) THEN
242 
243                  l1 = l1 - 1
244                  l  = l1
245 
246                ELSE
247 
248c              -- peut on etendre la colonne vers le haut ?
249 
250                  IF (l2 .EQ. nlay) EXIT
251 
252                  IF (zhc(i, l2+1) .GE. zhmc) EXIT
253c
254                  l2 = l2 + 1
255                  l  = l2
256c
257                END IF
258c
259cins$         End Loop
260              ENDDO
261c
262c          -- nouveau profil : constant (valeur moyenne)
263c
264              zalpha=0.
265              zum=0.
266              zvm=0.
267              do iq=1,nq
268                zqm(iq) = 0.
269              end do
270              DO l = l1, l2
271                if(ico2.ne.0) then
272                  zalpha=zalpha+
273     &            ABS(zhc(i,l)/(A+B*zqco2m) -zhm)*dsig(l)
274                else
275                  zalpha=zalpha+ABS(zh2(i,l)-zhm)*dsig(l)
276                endif
277                zh2(i, l) = zhm
278                zum=zum+dsig(l)*zu(i,l)
279                zvm=zvm+dsig(l)*zv(i,l)
280                do iq=1,nq
281                   zqm(iq) = zqm(iq)+dsig(l)*zq(i,l,iq)
282                end do
283              ENDDO
284              zalpha=zalpha/(zhm*(sig(l1)-sig(l2+1)))
285              zum=zum/(sig(l1)-sig(l2+1))
286              zvm=zvm/(sig(l1)-sig(l2+1))
287              do iq=1,nq
288                 zqm(iq) = zqm(iq)/(sig(l1)-sig(l2+1))
289              end do
290
291              IF(zalpha.GT.1.) THEN
292                 zalpha=1.
293              ELSE
294c                IF(zalpha.LT.0.) STOP
295                 IF(zalpha.LT.1.e-4) zalpha=1.e-4
296              ENDIF
297
298              DO l=l1,l2
299                 zu2(i,l)=zu2(i,l)+zalpha*(zum-zu2(i,l))
300                 zv2(i,l)=zv2(i,l)+zalpha*(zvm-zv2(i,l))
301                 do iq=1,nq
302c                  zq2(i,l,iq)=zq2(i,l,iq)+zalpha*(zqm(iq)-zq2(i,l,iq))
303                   zq2(i,l,iq)=zqm(iq)
304                 end do
305              ENDDO
306c              diag_alpha(i)=zalpha  !temporaire
307              if (ico2.ne.0) then
308                DO l=l1, l2
309                  zhc(i,l) = zh2(i,l)*(A*zq2(i,l,ico2)+B)
310                ENDDO
311              end if
312
313 
314              l2 = l2 + 1
315c
316            END IF   ! fin traitement instabilité entre l1 et l2.
317c                      On repart pour test à partir du l2 au dessus...
318          ENDDO   ! End Loop sur l2 vers le haut
319c
320      ENDDO
321c
322      DO l=1,nlay
323        DO ig=1,ngrid
324          pdhadj(ig,l)=(zh2(ig,l)-zh(ig,l))/ptimestep
325          pduadj(ig,l)=(zu2(ig,l)-zu(ig,l))/ptimestep
326          pdvadj(ig,l)=(zv2(ig,l)-zv(ig,l))/ptimestep
327        ENDDO
328      ENDDO
329
330      if(tracer) then
331        do iq=1, nq
332          do  l=1,nlay
333            do ig=1, ngrid
334              pdqadj(ig,l,iq)=(zq2(ig,l,iq)-zq(ig,l,iq))/ptimestep
335            end do
336          end do
337        end do
338      end if
339
340c     output
341!      if (ngrid.eq.1) then
342!         ig=1
343!         iq =1
344!         write(*,*)'**** l, pq(ig,l,iq),zq(ig,l,iq),zq2(ig,l,iq)' 
345!         do l=nlay,1,-1
346!           write(*,*) l, pq(ig,l,iq),zq(ig,l,iq),zq2(ig,l,iq)
347!         end do
348!      end if
349
350
351      RETURN
352      END
Note: See TracBrowser for help on using the repository browser.