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

Last change on this file since 4381 was 4381, checked in by evignon, 17 months ago

pour les downdrafts, suppression de la cle de compilation pour protection sous flag
iflag_thermals_down
+ stop si le flux compensatoire est vers le haut

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