source: LMDZ6/trunk/libf/phylmd/thermcell_down.F90 @ 4570

Last change on this file since 4570 was 4463, checked in by lguez, 21 months ago

Replace stop by call to abort_physiq

File size: 10.6 KB
RevLine 
[4437]1SUBROUTINE thermcell_updown_dq(ngrid,nlay,ptimestep,lmax,eup,dup,edn,ddn,masse,trac,dtrac)
[4351]2
[4437]3USE thermcell_ini_mod, ONLY: iflag_thermals_down
4
5
[4383]6!-----------------------------------------------------------------
7! thermcell_updown_dq: computes the tendency of tracers associated
8! with the presence of convective up/down drafts
9! This routine that has been collectively written during the
10! "ateliers downdrafts" in 2022/2023
11! Maelle, Frédéric, Catherine, Fleur, Florent, Etienne
12!------------------------------------------------------------------
[4351]13
14
[4365]15   IMPLICIT NONE
16
[4383]17! declarations
18!==============================================================
[4365]19
[4383]20! input/output
[4365]21
[4383]22   integer,intent(in)  :: ngrid ! number of horizontal grid points
23   integer, intent(in) :: nlay  ! number of vertical layers
24   real,intent(in) :: ptimestep ! time step of the physics [s]
25   real,intent(in), dimension(ngrid,nlay) :: eup ! entrainment to updrafts * dz [same unit as flux]
26   real,intent(in), dimension(ngrid,nlay) :: dup ! detrainment from updrafts * dz [same unit as flux]
27   real,intent(in), dimension(ngrid,nlay) :: edn ! entrainment to downdrafts * dz [same unit as flux]
28   real,intent(in), dimension(ngrid,nlay) :: ddn ! detrainment from downdrafts * dz [same unit as flux]
29   real,intent(in), dimension(ngrid,nlay) :: masse ! mass of layers = rho dz
[4396]30   real,intent(in), dimension(ngrid,nlay) :: trac ! tracer
[4383]31   integer, intent(in), dimension(ngrid) :: lmax ! max level index at which downdraft are present
[4396]32   real,intent(out),dimension(ngrid,nlay) ::dtrac ! tendance du traceur
[4383]33
[4365]34   
35! Local
36
[4437]37   real, dimension(ngrid,nlay+1) :: fup,fdn,fc,fthu,fthd,fthe,fthtot
38   real, dimension(ngrid,nlay) :: tracu,tracd,traci,tracold
39   real :: www, mstar_inv
[4365]40   integer ig,ilay
[4437]41   real, dimension(ngrid,nlay):: s1,s2,num !coefficients pour la resolution implicite
42   integer :: iflag_impl=1 ! 0 pour explicite, 1 pour implicite "classique", 2 pour implicite avec entrainement et detrainement
43   
[4365]44   fdn(:,:)=0.
[4377]45   fup(:,:)=0.
[4437]46   fc(:,:)=0.
[4377]47   fthu(:,:)=0.
48   fthd(:,:)=0.
49   fthe(:,:)=0.
50   fthtot(:,:)=0.
[4383]51   tracd(:,:)=0.
52   tracu(:,:)=0.
[4437]53   traci(:,:)=trac(:,:)
54   tracold(:,:)=trac(:,:)
55   s1(:,:)=0.
56   s2(:,:)=0.
57   num(:,:)=1.
[4365]58
[4437]59   if ( iflag_thermals_down < 10 ) then
[4463]60      call abort_physic("thermcell_updown_dq", &
61           'thermcell_down_dq = 0 or >= 10', 1)
[4437]62   else
63        iflag_impl=iflag_thermals_down-10
64   endif
65     
66
[4365]67   ! lmax : indice tel que fu(kmax+1)=0
[4383]68   ! Dans ce cas, pas besoin d'initialiser tracd(lmax) ( =trac(lmax) )
[4377]69   ! Boucle pour le downdraft
[4365]70   do ilay=nlay,1,-1
71      do ig=1,ngrid
[4438]72         !if ( lmax(ig) > nlay - 2 ) stop "les thermiques montent trop haut"
73         if (ilay.le.lmax(ig) .and. lmax(ig)>1 ) then
[4365]74            fdn(ig,ilay)=fdn(ig,ilay+1)+edn(ig,ilay)-ddn(ig,ilay)
[4438]75            if ( fdn(ig,ilay)+ddn(ig,ilay) > 0. ) then
76               www=fdn(ig,ilay+1)/ (fdn(ig,ilay)+ddn(ig,ilay))
[4377]77            else
[4438]78               www=0.
[4377]79            endif
[4438]80            tracd(ig,ilay)=www*tracd(ig,ilay+1) + (1.-www)*trac(ig,ilay)
[4365]81         endif
82      enddo
[4437]83   enddo !Fin boucle sur l'updraft
84   fdn(:,1)=0.
[4365]85
[4377]86   !Boucle pour l'updraft
87   do ilay=1,nlay,1
88      do ig=1,ngrid
[4396]89         if (ilay.lt.lmax(ig) .and. lmax(ig)>1) then
[4377]90            fup(ig,ilay+1)=fup(ig,ilay)+eup(ig,ilay)-dup(ig,ilay)
[4438]91            if (fup(ig,ilay+1)+dup(ig,ilay) > 0.) then
92               www=fup(ig,ilay)/(fup(ig,ilay+1)+dup(ig,ilay))
93            else
94               www=0.
95            endif
[4377]96            if (ilay == 1 ) then
[4383]97               tracu(ig,ilay)=trac(ig,ilay)
[4377]98            else
[4383]99               tracu(ig,ilay)=www*tracu(ig,ilay-1)+(1.-www)*trac(ig,ilay)
[4377]100            endif
101         endif
102      enddo
[4437]103      enddo !fin boucle sur le downdraft
104
105   ! Calcul des flux des traceurs dans les updraft et les downdrfat
106   ! et du flux de masse compensateur
107   ! en ilay=1 et nlay+1, fthu=0 et fthd=0
108   fthu(:,1)=0.
109   fthu(:,nlay+1)=0.
110   fthd(:,1)=0.
111   fthd(:,nlay+1)=0.
112   fc(:,1)=0.
113   fc(:,nlay+1)=0.
114   do ilay=2,nlay,1 !boucle sur les interfaces
[4377]115     do ig=1,ngrid
[4383]116       fthu(ig,ilay)=fup(ig,ilay)*tracu(ig,ilay-1)
117       fthd(ig,ilay)=-fdn(ig,ilay)*tracd(ig,ilay)
[4437]118       fc(ig,ilay)=fup(ig,ilay)-fdn(ig,ilay)
[4377]119     enddo
120   enddo
[4437]121   
122
123   !Boucle pour calculer le flux du traceur flux updraft, flux downdraft, flux compensatoire
124   !Methode explicite :
125   if(iflag_impl==0) then
126     do ilay=2,nlay,1
127       do ig=1,ngrid
128         !!!!ATTENTION HYPOTHESE de FLUX COMPENSATOIRE DESCENDANT ET DONC comme schema amont on va chercher trac au dessus!!!!!
129         !!!! tentative de prise en compte d'un flux compensatoire montant  !!!!
130         if (fup(ig,ilay)-fdn(ig,ilay) .lt. 0.) then
[4463]131            call abort_physic("thermcell_updown_dq", 'flux compensatoire '&
132                 // 'montant, cas non traite par thermcell_updown_dq', 1)
[4437]133            !fthe(ig,ilay)=(fup(ig,ilay)-fdn(ig,ilay))*trac(ig,ilay-1)
134         else
135            fthe(ig,ilay)=-(fup(ig,ilay)-fdn(ig,ilay))*trac(ig,ilay)
136         endif
137         !! si on voulait le prendre en compte on
138         !fthe(ig,ilay)=-(fup(ig,ilay)-fdn(ig,ilay))*trac(ig,ilay-1)
139         fthtot(ig,ilay)=fthu(ig,ilay)+fthd(ig,ilay)+fthe(ig,ilay)
140       enddo
[4377]141     enddo
[4437]142     !Boucle pour calculer trac
143     do ilay=1,nlay
144       do ig=1,ngrid
145         dtrac(ig,ilay)=(fthtot(ig,ilay)-fthtot(ig,ilay+1))/masse(ig,ilay)
146!         trac(ig,ilay)=trac(ig,ilay) + (fthtot(ig,ilay)-fthtot(ig,ilay+1))*(ptimestep/masse(ig,ilay))
147       enddo
148     enddo !fin du calculer de la tendance du traceur avec la methode explicite
[4365]149
[4437]150   !!! Reecriture du schéma explicite avec les notations du schéma implicite
151   else if(iflag_impl==-1) then
152     write(*,*) 'nouveau schéma explicite !!!'
153     !!! Calcul de s1
154     do ilay=1,nlay
155       do ig=1,ngrid
156         s1(ig,ilay)=fthu(ig,ilay)-fthu(ig,ilay+1)+fthd(ig,ilay)-fthd(ig,ilay+1)
157         s2(ig,ilay)=s1(ig,ilay)+fthe(ig,ilay)-fthe(ig,ilay+1)
158       enddo
159     enddo
[4365]160
[4437]161     do ilay=2,nlay,1
162       do ig=1,ngrid
163         if (fup(ig,ilay)-fdn(ig,ilay) .lt. 0.) then
[4463]164            call abort_physic("thermcell_updown_dq", 'flux compensatoire ' &
165                 // 'montant, cas non traite par thermcell_updown_dq', 1)
[4437]166         else
167            fthe(ig,ilay)=-(fup(ig,ilay)-fdn(ig,ilay))*trac(ig,ilay)
168         endif
169         fthtot(ig,ilay)=fthu(ig,ilay)+fthd(ig,ilay)+fthe(ig,ilay)
170       enddo
171     enddo
172     !Boucle pour calculer trac
173     do ilay=1,nlay
174       do ig=1,ngrid
175         ! dtrac(ig,ilay)=(fthtot(ig,ilay)-fthtot(ig,ilay+1))/masse(ig,ilay)
176         dtrac(ig,ilay)=(s1(ig,ilay)+fthe(ig,ilay)-fthe(ig,ilay+1))/masse(ig,ilay)
177!         trac(ig,ilay)=trac(ig,ilay) + (fthtot(ig,ilay)-fthtot(ig,ilay+1))*(ptimestep/masse(ig,ilay))
178!         trac(ig,ilay)=trac(ig,ilay) + (s1(ig,ilay)+fthe(ig,ilay)-fthe(ig,ilay+1))*(ptimestep/masse(ig,ilay))
179       enddo
180     enddo !fin du calculer de la tendance du traceur avec la methode explicite
[4377]181
[4437]182   else if (iflag_impl==1) then
183     do ilay=1,nlay
184       do ig=1,ngrid
185         s1(ig,ilay)=fthu(ig,ilay)-fthu(ig,ilay+1)+fthd(ig,ilay)-fthd(ig,ilay+1)
186       enddo
187     enddo
188     
189     !Boucle pour calculer traci = trac((t+dt)
190     do ilay=nlay-1,1,-1
191       do ig=1,ngrid
192         if((fup(ig,ilay)-fdn(ig,ilay)) .lt. 0) then
193            write(*,*) 'flux compensatoire montant, cas non traite par thermcell_updown_dq dans le cas d une resolution implicite, ilay : ', ilay
[4463]194            call abort_physic("thermcell_updown_dq", "", 1)
[4437]195         else
196           mstar_inv=ptimestep/masse(ig,ilay)
197           traci(ig,ilay)=((traci(ig,ilay+1)*fc(ig,ilay+1)+s1(ig,ilay))*mstar_inv+tracold(ig,ilay))/(1.+fc(ig,ilay)*mstar_inv)
198         endif
199       enddo
200     enddo
201     do ilay=1,nlay
202       do ig=1,ngrid
203         dtrac(ig,ilay)=(traci(ig,ilay)-tracold(ig,ilay))/ptimestep
204       enddo
205     enddo
[4377]206
[4437]207   else
[4463]208      call abort_physic("thermcell_updown_dq", &
209           'valeur de iflag_impl non prevue', 1)
[4437]210   endif
[4377]211
[4365]212 RETURN
213   END
214
215!=========================================================================
216
217   SUBROUTINE thermcell_down(ngrid,nlay,po,pt,pu,pv,pplay,pplev,  &
218     &           lmax,fup,eup,dup,theta)
219
220!--------------------------------------------------------------
[4377]221!thermcell_down: calcul des propri??t??s du panache descendant.
[4365]222!--------------------------------------------------------------
223
224
[4441]225   USE thermcell_ini_mod, ONLY : prt_level,RLvCp,RKAPPA,RETV,fact_thermals_down
[4351]226   IMPLICIT NONE
227
228! arguments
229
230   integer,intent(in) :: ngrid,nlay
[4365]231   real,intent(in), dimension(ngrid,nlay) :: po,pt,pu,pv,pplay,eup,dup
232   real,intent(in), dimension(ngrid,nlay) :: theta
[4351]233   real,intent(in), dimension(ngrid,nlay+1) :: pplev,fup
234   integer, intent(in), dimension(ngrid) :: lmax
235
236
237   
238! Local
239
[4365]240   real, dimension(ngrid,nlay) :: edn,ddn,thetad
[4351]241   real, dimension(ngrid,nlay+1) :: fdn
242
243   integer ig,ilay
244   real dqsat_dT
245   logical mask(ngrid,nlay)
246
247   edn(:,:)=0.
248   ddn(:,:)=0.
249   fdn(:,:)=0.
[4365]250   thetad(:,:)=0.
[4351]251
[4365]252   ! lmax : indice tel que fu(kmax+1)=0
[4351]253   
[4365]254   ! Dans ce cas, pas besoin d'initialiser thetad(lmax) ( =theta(lmax) )
[4351]255
[4365]256! FH MODIFS APRES REUNIONS POUR COMMISSIONS
257! quelques erreurs de declaration
[4377]258! probleme si lmax=1 ce qui a l'air d'??tre le cas en d??but de simu. Devrait ??tre 0 ?
[4365]259! Remarques :
[4377]260! on pourrait ??crire la formule de thetad
[4365]261!    www=fdn(ig,ilay+1)/ (fdn(ig,ilay)+ddn(ig,ilay))
262!    thetad(ig,ilay)= www * thetad(ig,ilay+1) + (1.-www) * theta(ig,ilay)
[4377]263! Elle a l'avantage de bien montr?? la conservation, l'id??e fondamentale dans le
[4365]264!   transport qu'on ne fait que sommer des "sources" au travers d'un "propagateur"
265!   (Green)
[4377]266! Elle montre aussi beaucoup plus clairement pourquoi on n'a pas ?? se souccier (trop)
267!   de la possible nulit?? du d??nominateur
[4365]268
269
270   do ilay=nlay,1,-1
[4351]271      do ig=1,ngrid
[4365]272         if (ilay.le.lmax(ig).and.lmax(ig)>1) then
[4441]273            edn(ig,ilay)=fact_thermals_down*dup(ig,ilay)
274            ddn(ig,ilay)=fact_thermals_down*eup(ig,ilay)
[4365]275            fdn(ig,ilay)=fdn(ig,ilay+1)+edn(ig,ilay)-ddn(ig,ilay)
276            thetad(ig,ilay)=( fdn(ig,ilay+1)*thetad(ig,ilay+1) + edn(ig,ilay)*theta(ig,ilay) ) / (fdn(ig,ilay)+ddn(ig,ilay))
[4351]277         endif
278      enddo
279   enddo
280
281   ! Suite du travail :
282   ! Ecrire la conservervation de theta_l dans le panache descendant
283   ! Eventuellement faire la transformation theta_l -> theta_v
[4377]284   ! Si l'air est sec (et qu'on oublie le c??t?? theta_v) on peut
[4351]285   ! se contenter de conserver theta.
286   !
[4377]287   ! Connaissant thetadn, on peut calculer la flotabilit??.
288   ! Connaissant la flotabilit??, on peut calculer w de proche en proche
289   ! On peut calculer le detrainement de facon ?? garder alpha*rho = cste
290   ! On en d??duit l'entrainement lat??ral
291   ! C'est le mod??le des mini-projets.
[4351]292
293!^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
294! Initialisations :
295!------------------
296
297
298!
299 RETURN
300   END
Note: See TracBrowser for help on using the repository browser.