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

Last change on this file since 4393 was 4383, checked in by evignon, 2 years ago

on renomme la variable theta de thermcell_updown_dq en trac et
on commente un peu l'entete du fichier

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