1 |
SUBROUTINE thermcell(ngrid, nlay, ptimestep, pplay, pplev, pphi, pu, pv, pt, & |
module thermcell_m |
|
po, pduadj, pdvadj, pdtadj, pdoadj, fm0, entr0, r_aspect, l_mix, w2di, tho) |
|
|
|
|
|
use dimens_m |
|
|
use dimphy |
|
|
use SUPHEC_M |
|
2 |
|
|
3 |
IMPLICIT NONE |
IMPLICIT NONE |
4 |
|
|
5 |
! Calcul du transport verticale dans la couche limite en presence |
contains |
|
! de "thermiques" explicitement representes |
|
|
|
|
|
! Réécriture à partir d'un listing papier à Habas, le 14/02/00 |
|
|
|
|
|
! le thermique est supposé homogène et dissipé par mélange avec |
|
|
! son environnement. la longueur l_mix contrôle l'efficacité du |
|
|
! mélange |
|
|
|
|
|
! Le calcul du transport des différentes espèces se fait en prenant |
|
|
! en compte: |
|
|
! 1. un flux de masse montant |
|
|
! 2. un flux de masse descendant |
|
|
! 3. un entrainement |
|
|
! 4. un detrainement |
|
|
|
|
|
! arguments: |
|
|
|
|
|
INTEGER ngrid, nlay, w2di, tho |
|
|
real ptimestep, l_mix, r_aspect |
|
|
REAL, intent(in):: pt(ngrid, nlay) |
|
|
real pdtadj(ngrid, nlay) |
|
|
REAL pu(ngrid, nlay), pduadj(ngrid, nlay) |
|
|
REAL pv(ngrid, nlay), pdvadj(ngrid, nlay) |
|
|
REAL po(ngrid, nlay), pdoadj(ngrid, nlay) |
|
|
REAL, intent(in):: pplay(ngrid, nlay) |
|
|
real, intent(in):: pplev(ngrid, nlay+1) |
|
|
real, intent(in):: pphi(ngrid, nlay) |
|
|
|
|
|
integer idetr |
|
|
save idetr |
|
|
data idetr/3/ |
|
|
|
|
|
! local: |
|
|
|
|
|
INTEGER ig, k, l, lmaxa(klon), lmix(klon) |
|
|
real zsortie1d(klon) |
|
|
! CR: on remplace lmax(klon, klev+1) |
|
|
INTEGER lmax(klon), lmin(klon), lentr(klon) |
|
|
real linter(klon) |
|
|
real zmix(klon), fracazmix(klon) |
|
|
|
|
|
real zmax(klon), zw, zz, zw2(klon, klev+1), ztva(klon, klev), zzz |
|
|
|
|
|
real zlev(klon, klev+1), zlay(klon, klev) |
|
|
REAL zh(klon, klev), zdhadj(klon, klev) |
|
|
REAL ztv(klon, klev) |
|
|
real zu(klon, klev), zv(klon, klev), zo(klon, klev) |
|
|
REAL wh(klon, klev+1) |
|
|
real wu(klon, klev+1), wv(klon, klev+1), wo(klon, klev+1) |
|
|
real zla(klon, klev+1) |
|
|
real zwa(klon, klev+1) |
|
|
real zld(klon, klev+1) |
|
|
real zwd(klon, klev+1) |
|
|
real zsortie(klon, klev) |
|
|
real zva(klon, klev) |
|
|
real zua(klon, klev) |
|
|
real zoa(klon, klev) |
|
|
|
|
|
real zha(klon, klev) |
|
|
real wa_moy(klon, klev+1) |
|
|
real fraca(klon, klev+1) |
|
|
real fracc(klon, klev+1) |
|
|
real zf, zf2 |
|
|
real thetath2(klon, klev), wth2(klon, klev) |
|
|
common/comtherm/thetath2, wth2 |
|
|
|
|
|
real count_time |
|
|
integer isplit, nsplit, ialt |
|
|
parameter (nsplit=10) |
|
|
data isplit/0/ |
|
|
save isplit |
|
|
|
|
|
logical sorties |
|
|
real rho(klon, klev), rhobarz(klon, klev+1), masse(klon, klev) |
|
|
real zpspsk(klon, klev) |
|
|
|
|
|
real wmax(klon), wmaxa(klon) |
|
|
real wa(klon, klev, klev+1) |
|
|
real wd(klon, klev+1) |
|
|
real larg_part(klon, klev, klev+1) |
|
|
real fracd(klon, klev+1) |
|
|
real xxx(klon, klev+1) |
|
|
real larg_cons(klon, klev+1) |
|
|
real larg_detr(klon, klev+1) |
|
|
real fm0(klon, klev+1), entr0(klon, klev), detr(klon, klev) |
|
|
real pu_therm(klon, klev), pv_therm(klon, klev) |
|
|
real fm(klon, klev+1), entr(klon, klev) |
|
|
real fmc(klon, klev+1) |
|
|
|
|
|
!CR:nouvelles variables |
|
|
real f_star(klon, klev+1), entr_star(klon, klev) |
|
|
real entr_star_tot(klon), entr_star2(klon) |
|
|
real f(klon), f0(klon) |
|
|
real zlevinter(klon) |
|
|
logical first |
|
|
data first /.false./ |
|
|
save first |
|
|
|
|
|
character*2 str2 |
|
|
character*10 str10 |
|
|
|
|
|
LOGICAL vtest(klon), down |
|
|
|
|
|
EXTERNAL SCOPY |
|
|
|
|
|
integer ncorrec, ll |
|
|
save ncorrec |
|
|
data ncorrec/0/ |
|
|
|
|
|
!----------------------------------------------------------------------- |
|
|
|
|
|
! initialisation: |
|
|
|
|
|
sorties=.true. |
|
|
IF(ngrid.NE.klon) THEN |
|
|
PRINT * |
|
|
PRINT *, 'STOP dans convadj' |
|
|
PRINT *, 'ngrid =', ngrid |
|
|
PRINT *, 'klon =', klon |
|
|
ENDIF |
|
|
|
|
|
! incrementation eventuelle de tendances precedentes: |
|
|
|
|
|
print *, '0 OK convect8' |
|
|
|
|
|
DO l=1, nlay |
|
|
DO ig=1, ngrid |
|
|
zpspsk(ig, l)=(pplay(ig, l)/pplev(ig, 1))**RKAPPA |
|
|
zh(ig, l)=pt(ig, l)/zpspsk(ig, l) |
|
|
zu(ig, l)=pu(ig, l) |
|
|
zv(ig, l)=pv(ig, l) |
|
|
zo(ig, l)=po(ig, l) |
|
|
ztv(ig, l)=zh(ig, l)*(1.+0.61*zo(ig, l)) |
|
|
end DO |
|
|
end DO |
|
|
|
|
|
print *, '1 OK convect8' |
|
|
|
|
|
! + + + + + + + + + + + |
|
|
|
|
|
! wa, fraca, wd, fracd -------------------- zlev(2), rhobarz |
|
|
! wh, wt, wo ... |
|
|
|
|
|
! + + + + + + + + + + + zh, zu, zv, zo, rho |
|
|
|
|
|
! -------------------- zlev(1) |
|
|
! \\\\\\\\\\\\\\\\\\\\ |
|
|
|
|
|
! Calcul des altitudes des couches |
|
|
|
|
|
do l=2, nlay |
|
|
do ig=1, ngrid |
|
|
zlev(ig, l)=0.5*(pphi(ig, l)+pphi(ig, l-1))/RG |
|
|
enddo |
|
|
enddo |
|
|
do ig=1, ngrid |
|
|
zlev(ig, 1)=0. |
|
|
zlev(ig, nlay+1)=(2.*pphi(ig, klev)-pphi(ig, klev-1))/RG |
|
|
enddo |
|
|
do l=1, nlay |
|
|
do ig=1, ngrid |
|
|
zlay(ig, l)=pphi(ig, l)/RG |
|
|
enddo |
|
|
enddo |
|
|
|
|
|
! Calcul des densites |
|
|
|
|
|
do l=1, nlay |
|
|
do ig=1, ngrid |
|
|
rho(ig, l)=pplay(ig, l)/(zpspsk(ig, l)*RD*zh(ig, l)) |
|
|
enddo |
|
|
enddo |
|
|
|
|
|
do l=2, nlay |
|
|
do ig=1, ngrid |
|
|
rhobarz(ig, l)=0.5*(rho(ig, l)+rho(ig, l-1)) |
|
|
enddo |
|
|
enddo |
|
|
|
|
|
do k=1, nlay |
|
|
do l=1, nlay+1 |
|
|
do ig=1, ngrid |
|
|
wa(ig, k, l)=0. |
|
|
enddo |
|
|
enddo |
|
|
enddo |
|
|
|
|
|
! Calcul de w2, quarre de w a partir de la cape |
|
|
! a partir de w2, on calcule wa, vitesse de l'ascendance |
|
|
|
|
|
! ATTENTION: Dans cette version, pour cause d'economie de memoire, |
|
|
! w2 est stoke dans wa |
|
|
|
|
|
! ATTENTION: dans convect8, on n'utilise le calcule des wa |
|
|
! independants par couches que pour calculer l'entrainement |
|
|
! a la base et la hauteur max de l'ascendance. |
|
|
|
|
|
! Indicages: |
|
|
! l'ascendance provenant du niveau k traverse l'interface l avec |
|
|
! une vitesse wa(k, l). |
|
|
|
|
|
! -------------------- |
|
|
|
|
|
! + + + + + + + + + + |
|
|
|
|
|
! wa(k, l) ---- -------------------- l |
|
|
! /\ |
|
|
! /||\ + + + + + + + + + + |
|
|
! || |
|
|
! || -------------------- |
|
|
! || |
|
|
! || + + + + + + + + + + |
|
|
! || |
|
|
! || -------------------- |
|
|
! ||__ |
|
|
! |___ + + + + + + + + + + k |
|
|
|
|
|
! -------------------- |
|
|
|
|
|
!CR: ponderation entrainement des couches instables |
|
|
!def des entr_star tels que entr=f*entr_star |
|
|
do l=1, klev |
|
|
do ig=1, ngrid |
|
|
entr_star(ig, l)=0. |
|
|
enddo |
|
|
enddo |
|
|
! determination de la longueur de la couche d entrainement |
|
|
do ig=1, ngrid |
|
|
lentr(ig)=1 |
|
|
enddo |
|
|
|
|
|
!on ne considere que les premieres couches instables |
|
|
do k=nlay-2, 1, -1 |
|
|
do ig=1, ngrid |
|
|
if (ztv(ig, k).gt.ztv(ig, k+1).and. & |
|
|
ztv(ig, k+1).le.ztv(ig, k+2)) then |
|
|
lentr(ig)=k |
|
|
endif |
|
|
enddo |
|
|
enddo |
|
|
|
|
|
! determination du lmin: couche d ou provient le thermique |
|
|
do ig=1, ngrid |
|
|
lmin(ig)=1 |
|
|
enddo |
|
|
do ig=1, ngrid |
|
|
do l=nlay, 2, -1 |
|
|
if (ztv(ig, l-1).gt.ztv(ig, l)) then |
|
|
lmin(ig)=l-1 |
|
|
endif |
|
|
enddo |
|
|
enddo |
|
|
|
|
|
! definition de l'entrainement des couches |
|
|
do l=1, klev-1 |
|
|
do ig=1, ngrid |
|
|
if (ztv(ig, l).gt.ztv(ig, l+1).and. & |
|
|
l.ge.lmin(ig).and.l.le.lentr(ig)) then |
|
|
entr_star(ig, l)=(ztv(ig, l)-ztv(ig, l+1))* & |
|
|
(zlev(ig, l+1)-zlev(ig, l)) |
|
|
endif |
|
|
enddo |
|
|
enddo |
|
|
! pas de thermique si couches 1->5 stables |
|
|
do ig=1, ngrid |
|
|
if (lmin(ig).gt.5) then |
|
|
do l=1, klev |
|
|
entr_star(ig, l)=0. |
|
|
enddo |
|
|
endif |
|
|
enddo |
|
|
! calcul de l entrainement total |
|
|
do ig=1, ngrid |
|
|
entr_star_tot(ig)=0. |
|
|
enddo |
|
|
do ig=1, ngrid |
|
|
do k=1, klev |
|
|
entr_star_tot(ig)=entr_star_tot(ig)+entr_star(ig, k) |
|
|
enddo |
|
|
enddo |
|
|
|
|
|
print *, 'fin calcul entr_star' |
|
|
do k=1, klev |
|
|
do ig=1, ngrid |
|
|
ztva(ig, k)=ztv(ig, k) |
|
|
enddo |
|
|
enddo |
|
|
|
|
|
do k=1, klev+1 |
|
|
do ig=1, ngrid |
|
|
zw2(ig, k)=0. |
|
|
fmc(ig, k)=0. |
|
|
|
|
|
f_star(ig, k)=0. |
|
|
|
|
|
larg_cons(ig, k)=0. |
|
|
larg_detr(ig, k)=0. |
|
|
wa_moy(ig, k)=0. |
|
|
enddo |
|
|
enddo |
|
|
|
|
|
do ig=1, ngrid |
|
|
linter(ig)=1. |
|
|
lmaxa(ig)=1 |
|
|
lmix(ig)=1 |
|
|
wmaxa(ig)=0. |
|
|
enddo |
|
|
|
|
|
do l=1, nlay-2 |
|
|
do ig=1, ngrid |
|
|
if (ztv(ig, l).gt.ztv(ig, l+1) & |
|
|
.and.entr_star(ig, l).gt.1.e-10 & |
|
|
.and.zw2(ig, l).lt.1e-10) then |
|
|
f_star(ig, l+1)=entr_star(ig, l) |
|
|
!test:calcul de dteta |
|
|
zw2(ig, l+1)=2.*RG*(ztv(ig, l)-ztv(ig, l+1))/ztv(ig, l+1) & |
|
|
*(zlev(ig, l+1)-zlev(ig, l)) & |
|
|
*0.4*pphi(ig, l)/(pphi(ig, l+1)-pphi(ig, l)) |
|
|
larg_detr(ig, l)=0. |
|
|
else if ((zw2(ig, l).ge.1e-10).and. & |
|
|
(f_star(ig, l)+entr_star(ig, l).gt.1.e-10)) then |
|
|
f_star(ig, l+1)=f_star(ig, l)+entr_star(ig, l) |
|
|
ztva(ig, l)=(f_star(ig, l)*ztva(ig, l-1)+entr_star(ig, l) & |
|
|
*ztv(ig, l))/f_star(ig, l+1) |
|
|
zw2(ig, l+1)=zw2(ig, l)*(f_star(ig, l)/f_star(ig, l+1))**2+ & |
|
|
2.*RG*(ztva(ig, l)-ztv(ig, l))/ztv(ig, l) & |
|
|
*(zlev(ig, l+1)-zlev(ig, l)) |
|
|
endif |
|
|
! determination de zmax continu par interpolation lineaire |
|
|
if (zw2(ig, l+1).lt.0.) then |
|
|
if (abs(zw2(ig, l+1)-zw2(ig, l)).lt.1e-10) then |
|
|
print *, 'pb linter' |
|
|
endif |
|
|
linter(ig)=(l*(zw2(ig, l+1)-zw2(ig, l)) & |
|
|
-zw2(ig, l))/(zw2(ig, l+1)-zw2(ig, l)) |
|
|
zw2(ig, l+1)=0. |
|
|
lmaxa(ig)=l |
|
|
else |
|
|
if (zw2(ig, l+1).lt.0.) then |
|
|
print *, 'pb1 zw2<0' |
|
|
endif |
|
|
wa_moy(ig, l+1)=sqrt(zw2(ig, l+1)) |
|
|
endif |
|
|
if (wa_moy(ig, l+1).gt.wmaxa(ig)) then |
|
|
! lmix est le niveau de la couche ou w (wa_moy) est maximum |
|
|
lmix(ig)=l+1 |
|
|
wmaxa(ig)=wa_moy(ig, l+1) |
|
|
endif |
|
|
enddo |
|
|
enddo |
|
|
print *, 'fin calcul zw2' |
|
|
|
|
|
! Calcul de la couche correspondant a la hauteur du thermique |
|
|
do ig=1, ngrid |
|
|
lmax(ig)=lentr(ig) |
|
|
enddo |
|
|
do ig=1, ngrid |
|
|
do l=nlay, lentr(ig)+1, -1 |
|
|
if (zw2(ig, l).le.1.e-10) then |
|
|
lmax(ig)=l-1 |
|
|
endif |
|
|
enddo |
|
|
enddo |
|
|
! pas de thermique si couches 1->5 stables |
|
|
do ig=1, ngrid |
|
|
if (lmin(ig).gt.5) then |
|
|
lmax(ig)=1 |
|
|
lmin(ig)=1 |
|
|
endif |
|
|
enddo |
|
|
|
|
|
! Determination de zw2 max |
|
|
do ig=1, ngrid |
|
|
wmax(ig)=0. |
|
|
enddo |
|
|
|
|
|
do l=1, nlay |
|
|
do ig=1, ngrid |
|
|
if (l.le.lmax(ig)) then |
|
|
if (zw2(ig, l).lt.0.)then |
|
|
print *, 'pb2 zw2<0' |
|
|
endif |
|
|
zw2(ig, l)=sqrt(zw2(ig, l)) |
|
|
wmax(ig)=max(wmax(ig), zw2(ig, l)) |
|
|
else |
|
|
zw2(ig, l)=0. |
|
|
endif |
|
|
enddo |
|
|
enddo |
|
|
|
|
|
! Longueur caracteristique correspondant a la hauteur des thermiques. |
|
|
do ig=1, ngrid |
|
|
zmax(ig)=0. |
|
|
zlevinter(ig)=zlev(ig, 1) |
|
|
enddo |
|
|
do ig=1, ngrid |
|
|
! calcul de zlevinter |
|
|
zlevinter(ig)=(zlev(ig, lmax(ig)+1)-zlev(ig, lmax(ig)))* & |
|
|
linter(ig)+zlev(ig, lmax(ig))-lmax(ig)*(zlev(ig, lmax(ig)+1) & |
|
|
-zlev(ig, lmax(ig))) |
|
|
zmax(ig)=max(zmax(ig), zlevinter(ig)-zlev(ig, lmin(ig))) |
|
|
enddo |
|
|
|
|
|
print *, 'avant fermeture' |
|
|
! Fermeture, determination de f |
|
|
do ig=1, ngrid |
|
|
entr_star2(ig)=0. |
|
|
enddo |
|
|
do ig=1, ngrid |
|
|
if (entr_star_tot(ig).LT.1.e-10) then |
|
|
f(ig)=0. |
|
|
else |
|
|
do k=lmin(ig), lentr(ig) |
|
|
entr_star2(ig)=entr_star2(ig)+entr_star(ig, k)**2 & |
|
|
/(rho(ig, k)*(zlev(ig, k+1)-zlev(ig, k))) |
|
|
enddo |
|
|
! Nouvelle fermeture |
|
|
f(ig)=wmax(ig)/(max(500., zmax(ig))*r_aspect & |
|
|
*entr_star2(ig))*entr_star_tot(ig) |
|
|
endif |
|
|
enddo |
|
|
print *, 'apres fermeture' |
|
|
|
|
|
! Calcul de l'entrainement |
|
|
do k=1, klev |
|
|
do ig=1, ngrid |
|
|
entr(ig, k)=f(ig)*entr_star(ig, k) |
|
|
enddo |
|
|
enddo |
|
|
! Calcul des flux |
|
|
do ig=1, ngrid |
|
|
do l=1, lmax(ig)-1 |
|
|
fmc(ig, l+1)=fmc(ig, l)+entr(ig, l) |
|
|
enddo |
|
|
enddo |
|
|
|
|
|
! determination de l'indice du debut de la mixed layer ou w decroit |
|
|
|
|
|
! calcul de la largeur de chaque ascendance dans le cas conservatif. |
|
|
! dans ce cas simple, on suppose que la largeur de l'ascendance provenant |
|
|
! d'une couche est égale à la hauteur de la couche alimentante. |
|
|
! La vitesse maximale dans l'ascendance est aussi prise comme estimation |
|
|
! de la vitesse d'entrainement horizontal dans la couche alimentante. |
|
|
|
|
|
do l=2, nlay |
|
|
do ig=1, ngrid |
|
|
if (l.le.lmaxa(ig)) then |
|
|
zw=max(wa_moy(ig, l), 1.e-10) |
|
|
larg_cons(ig, l)=zmax(ig)*r_aspect & |
|
|
*fmc(ig, l)/(rhobarz(ig, l)*zw) |
|
|
endif |
|
|
enddo |
|
|
enddo |
|
|
|
|
|
do l=2, nlay |
|
|
do ig=1, ngrid |
|
|
if (l.le.lmaxa(ig)) then |
|
|
if ((l_mix*zlev(ig, l)).lt.0.)then |
|
|
print *, 'pb l_mix*zlev<0' |
|
|
endif |
|
|
larg_detr(ig, l)=sqrt(l_mix*zlev(ig, l)) |
|
|
endif |
|
|
enddo |
|
|
enddo |
|
|
|
|
|
! calcul de la fraction de la maille concernée par l'ascendance en tenant |
|
|
! compte de l'epluchage du thermique. |
|
|
|
|
|
!CR def de zmix continu (profil parabolique des vitesses) |
|
|
do ig=1, ngrid |
|
|
if (lmix(ig).gt.1.) then |
|
|
if (((zw2(ig, lmix(ig)-1)-zw2(ig, lmix(ig))) & |
|
|
*((zlev(ig, lmix(ig)))-(zlev(ig, lmix(ig)+1))) & |
|
|
-(zw2(ig, lmix(ig))-zw2(ig, lmix(ig)+1)) & |
|
|
*((zlev(ig, lmix(ig)-1))-(zlev(ig, lmix(ig))))).gt.1e-10) & |
|
|
then |
|
|
|
|
|
zmix(ig)=((zw2(ig, lmix(ig)-1)-zw2(ig, lmix(ig))) & |
|
|
*((zlev(ig, lmix(ig)))**2-(zlev(ig, lmix(ig)+1))**2) & |
|
|
-(zw2(ig, lmix(ig))-zw2(ig, lmix(ig)+1)) & |
|
|
*((zlev(ig, lmix(ig)-1))**2-(zlev(ig, lmix(ig)))**2)) & |
|
|
/(2.*((zw2(ig, lmix(ig)-1)-zw2(ig, lmix(ig))) & |
|
|
*((zlev(ig, lmix(ig)))-(zlev(ig, lmix(ig)+1))) & |
|
|
-(zw2(ig, lmix(ig))-zw2(ig, lmix(ig)+1)) & |
|
|
*((zlev(ig, lmix(ig)-1))-(zlev(ig, lmix(ig)))))) |
|
|
else |
|
|
zmix(ig)=zlev(ig, lmix(ig)) |
|
|
print *, 'pb zmix' |
|
|
endif |
|
|
else |
|
|
zmix(ig)=0. |
|
|
endif |
|
|
|
|
|
if ((zmax(ig)-zmix(ig)).lt.0.) then |
|
|
zmix(ig)=0.99*zmax(ig) |
|
|
endif |
|
|
enddo |
|
|
|
|
|
! calcul du nouveau lmix correspondant |
|
|
do ig=1, ngrid |
|
|
do l=1, klev |
|
|
if (zmix(ig).ge.zlev(ig, l).and. & |
|
|
zmix(ig).lt.zlev(ig, l+1)) then |
|
|
lmix(ig)=l |
|
|
endif |
|
|
enddo |
|
|
enddo |
|
|
|
|
|
do l=2, nlay |
|
|
do ig=1, ngrid |
|
|
if(larg_cons(ig, l).gt.1.) then |
|
|
fraca(ig, l)=(larg_cons(ig, l)-larg_detr(ig, l)) & |
|
|
/(r_aspect*zmax(ig)) |
|
|
fraca(ig, l)=max(fraca(ig, l), 0.) |
|
|
fraca(ig, l)=min(fraca(ig, l), 0.5) |
|
|
fracd(ig, l)=1.-fraca(ig, l) |
|
|
fracc(ig, l)=larg_cons(ig, l)/(r_aspect*zmax(ig)) |
|
|
else |
|
|
fraca(ig, l)=0. |
|
|
fracc(ig, l)=0. |
|
|
fracd(ig, l)=1. |
|
|
endif |
|
|
enddo |
|
|
enddo |
|
|
!CR: calcul de fracazmix |
|
|
do ig=1, ngrid |
|
|
fracazmix(ig)=(fraca(ig, lmix(ig)+1)-fraca(ig, lmix(ig)))/ & |
|
|
(zlev(ig, lmix(ig)+1)-zlev(ig, lmix(ig)))*zmix(ig) & |
|
|
+fraca(ig, lmix(ig))-zlev(ig, lmix(ig))*(fraca(ig, lmix(ig)+1) & |
|
|
-fraca(ig, lmix(ig)))/(zlev(ig, lmix(ig)+1)-zlev(ig, lmix(ig))) |
|
|
enddo |
|
|
|
|
|
do l=2, nlay |
|
|
do ig=1, ngrid |
|
|
if(larg_cons(ig, l).gt.1.) then |
|
|
if (l.gt.lmix(ig)) then |
|
|
if (zmax(ig)-zmix(ig).lt.1.e-10) then |
|
|
xxx(ig, l)=(lmaxa(ig)+1.-l)/(lmaxa(ig)+1.-lmix(ig)) |
|
|
else |
|
|
xxx(ig, l)=(zmax(ig)-zlev(ig, l))/(zmax(ig)-zmix(ig)) |
|
|
endif |
|
|
if (idetr.eq.0) then |
|
|
fraca(ig, l)=fracazmix(ig) |
|
|
else if (idetr.eq.1) then |
|
|
fraca(ig, l)=fracazmix(ig)*xxx(ig, l) |
|
|
else if (idetr.eq.2) then |
|
|
fraca(ig, l)=fracazmix(ig)*(1.-(1.-xxx(ig, l))**2) |
|
|
else |
|
|
fraca(ig, l)=fracazmix(ig)*xxx(ig, l)**2 |
|
|
endif |
|
|
fraca(ig, l)=max(fraca(ig, l), 0.) |
|
|
fraca(ig, l)=min(fraca(ig, l), 0.5) |
|
|
fracd(ig, l)=1.-fraca(ig, l) |
|
|
fracc(ig, l)=larg_cons(ig, l)/(r_aspect*zmax(ig)) |
|
|
endif |
|
|
endif |
|
|
enddo |
|
|
enddo |
|
|
|
|
|
print *, 'fin calcul fraca' |
|
|
|
|
|
! Calcul de fracd, wd |
|
|
! somme wa - wd = 0 |
|
|
|
|
|
do ig=1, ngrid |
|
|
fm(ig, 1)=0. |
|
|
fm(ig, nlay+1)=0. |
|
|
enddo |
|
|
|
|
|
do l=2, nlay |
|
|
do ig=1, ngrid |
|
|
fm(ig, l)=fraca(ig, l)*wa_moy(ig, l)*rhobarz(ig, l) |
|
|
if (entr(ig, l-1).lt.1e-10.and.fm(ig, l).gt.fm(ig, l-1) & |
|
|
.and.l.gt.lmix(ig)) then |
|
|
fm(ig, l)=fm(ig, l-1) |
|
|
endif |
|
|
enddo |
|
|
do ig=1, ngrid |
|
|
if(fracd(ig, l).lt.0.1) then |
|
|
stop'fracd trop petit' |
|
|
else |
|
|
! vitesse descendante "diagnostique" |
|
|
wd(ig, l)=fm(ig, l)/(fracd(ig, l)*rhobarz(ig, l)) |
|
|
endif |
|
|
enddo |
|
|
enddo |
|
|
|
|
|
do l=1, nlay |
|
|
do ig=1, ngrid |
|
|
masse(ig, l)=(pplev(ig, l)-pplev(ig, l+1))/RG |
|
|
enddo |
|
|
enddo |
|
|
|
|
|
print *, '12 OK convect8' |
|
|
|
|
|
! calcul du transport vertical |
|
|
|
|
|
!CR:redefinition du entr |
|
|
do l=1, nlay |
|
|
do ig=1, ngrid |
|
|
detr(ig, l)=fm(ig, l)+entr(ig, l)-fm(ig, l+1) |
|
|
if (detr(ig, l).lt.0.) then |
|
|
entr(ig, l)=entr(ig, l)-detr(ig, l) |
|
|
detr(ig, l)=0. |
|
|
endif |
|
|
enddo |
|
|
enddo |
|
|
|
|
|
if (w2di.eq.1) then |
|
|
fm0=fm0+ptimestep*(fm-fm0)/float(tho) |
|
|
entr0=entr0+ptimestep*(entr-entr0)/float(tho) |
|
|
else |
|
|
fm0=fm |
|
|
entr0=entr |
|
|
endif |
|
|
|
|
|
if (1.eq.1) then |
|
|
call dqthermcell(ngrid, nlay, ptimestep, fm0, entr0, masse & |
|
|
, zh, zdhadj, zha) |
|
|
call dqthermcell(ngrid, nlay, ptimestep, fm0, entr0, masse & |
|
|
, zo, pdoadj, zoa) |
|
|
else |
|
|
call dqthermcell2(ngrid, nlay, ptimestep, fm0, entr0, masse, fraca & |
|
|
, zh, zdhadj, zha) |
|
|
call dqthermcell2(ngrid, nlay, ptimestep, fm0, entr0, masse, fraca & |
|
|
, zo, pdoadj, zoa) |
|
|
endif |
|
|
|
|
|
if (1.eq.0) then |
|
|
call dvthermcell2(ngrid, nlay, ptimestep, fm0, entr0, masse & |
|
|
, fraca, zmax & |
|
|
, zu, zv, pduadj, pdvadj, zua, zva) |
|
|
else |
|
|
call dqthermcell(ngrid, nlay, ptimestep, fm0, entr0, masse & |
|
|
, zu, pduadj, zua) |
|
|
call dqthermcell(ngrid, nlay, ptimestep, fm0, entr0, masse & |
|
|
, zv, pdvadj, zva) |
|
|
endif |
|
|
|
|
|
do l=1, nlay |
|
|
do ig=1, ngrid |
|
|
zf=0.5*(fracc(ig, l)+fracc(ig, l+1)) |
|
|
zf2=zf/(1.-zf) |
|
|
thetath2(ig, l)=zf2*(zha(ig, l)-zh(ig, l))**2 |
|
|
wth2(ig, l)=zf2*(0.5*(wa_moy(ig, l)+wa_moy(ig, l+1)))**2 |
|
|
enddo |
|
|
enddo |
|
|
|
|
|
do l=1, nlay |
|
|
do ig=1, ngrid |
|
|
pdtadj(ig, l)=zdhadj(ig, l)*zpspsk(ig, l) |
|
|
enddo |
|
|
enddo |
|
|
|
|
|
print *, '14 OK convect8' |
|
|
|
|
|
! Calculs pour les sorties |
|
|
|
|
|
if(sorties) then |
|
|
do l=1, nlay |
|
|
do ig=1, ngrid |
|
|
zla(ig, l)=(1.-fracd(ig, l))*zmax(ig) |
|
|
zld(ig, l)=fracd(ig, l)*zmax(ig) |
|
|
if(1.-fracd(ig, l).gt.1.e-10) & |
|
|
zwa(ig, l)=wd(ig, l)*fracd(ig, l)/(1.-fracd(ig, l)) |
|
|
enddo |
|
|
enddo |
|
6 |
|
|
7 |
isplit=isplit+1 |
SUBROUTINE thermcell(ngrid, nlay, ptimestep, pplay, pplev, pphi, pu, pv, pt, & |
8 |
endif |
po, pduadj, pdvadj, pdtadj, pdoadj, fm0, entr0, r_aspect, l_mix, w2di, & |
9 |
|
tho) |
10 |
|
|
11 |
|
! Calcul du transport vertical dans la couche limite en pr\'esence |
12 |
|
! de "thermiques" explicitement repr\'esent\'es. R\'ecriture \`a partir |
13 |
|
! d'un listing papier \`a Habas, le 14/02/00. Le thermique est |
14 |
|
! suppos\'e homog\`ene et dissip\'e par m\'elange avec son |
15 |
|
! environnement. La longueur "l_mix" contr\^ole l'efficacit\'e du |
16 |
|
! m\'elange. Le calcul du transport des diff\'erentes esp\`eces se fait |
17 |
|
! en prenant en compte : |
18 |
|
! 1. un flux de masse montant |
19 |
|
! 2. un flux de masse descendant |
20 |
|
! 3. un entra\^inement |
21 |
|
! 4. un d\'etra\^inement |
22 |
|
|
23 |
|
USE dimphy, ONLY : klev, klon |
24 |
|
USE suphec_m, ONLY : rd, rg, rkappa |
25 |
|
|
26 |
|
! arguments: |
27 |
|
|
28 |
|
INTEGER ngrid, nlay, w2di |
29 |
|
real tho |
30 |
|
real ptimestep, l_mix, r_aspect |
31 |
|
REAL, intent(in):: pt(ngrid, nlay) |
32 |
|
real pdtadj(ngrid, nlay) |
33 |
|
REAL, intent(in):: pu(ngrid, nlay) |
34 |
|
real pduadj(ngrid, nlay) |
35 |
|
REAL, intent(in):: pv(ngrid, nlay) |
36 |
|
real pdvadj(ngrid, nlay) |
37 |
|
REAL po(ngrid, nlay), pdoadj(ngrid, nlay) |
38 |
|
REAL, intent(in):: pplay(ngrid, nlay) |
39 |
|
real, intent(in):: pplev(ngrid, nlay+1) |
40 |
|
real, intent(in):: pphi(ngrid, nlay) |
41 |
|
|
42 |
|
integer idetr |
43 |
|
save idetr |
44 |
|
data idetr/3/ |
45 |
|
|
46 |
|
! local: |
47 |
|
|
48 |
|
INTEGER ig, k, l, lmaxa(klon), lmix(klon) |
49 |
|
! CR: on remplace lmax(klon, klev+1) |
50 |
|
INTEGER lmax(klon), lmin(klon), lentr(klon) |
51 |
|
real linter(klon) |
52 |
|
real zmix(klon), fracazmix(klon) |
53 |
|
|
54 |
|
real zmax(klon), zw, zw2(klon, klev+1), ztva(klon, klev) |
55 |
|
|
56 |
|
real zlev(klon, klev+1) |
57 |
|
REAL zh(klon, klev), zdhadj(klon, klev) |
58 |
|
REAL ztv(klon, klev) |
59 |
|
real zu(klon, klev), zv(klon, klev), zo(klon, klev) |
60 |
|
real zva(klon, klev) |
61 |
|
real zua(klon, klev) |
62 |
|
real zoa(klon, klev) |
63 |
|
|
64 |
|
real zha(klon, klev) |
65 |
|
real wa_moy(klon, klev+1) |
66 |
|
real fraca(klon, klev+1) |
67 |
|
real fracc(klon, klev+1) |
68 |
|
real zf, zf2 |
69 |
|
real thetath2(klon, klev), wth2(klon, klev) |
70 |
|
common/comtherm/thetath2, wth2 |
71 |
|
|
72 |
|
integer nsplit |
73 |
|
parameter (nsplit=10) |
74 |
|
|
75 |
|
real rho(klon, klev), rhobarz(klon, klev+1), masse(klon, klev) |
76 |
|
real zpspsk(klon, klev) |
77 |
|
|
78 |
|
real wmax(klon), wmaxa(klon) |
79 |
|
real fracd(klon, klev+1) |
80 |
|
real xxx(klon, klev+1) |
81 |
|
real larg_cons(klon, klev+1) |
82 |
|
real larg_detr(klon, klev+1) |
83 |
|
real fm0(klon, klev+1), entr0(klon, klev), detr(klon, klev) |
84 |
|
real fm(klon, klev+1), entr(klon, klev) |
85 |
|
real fmc(klon, klev+1) |
86 |
|
|
87 |
|
!CR:nouvelles variables |
88 |
|
real f_star(klon, klev+1), entr_star(klon, klev) |
89 |
|
real entr_star_tot(klon), entr_star2(klon) |
90 |
|
real f(klon) |
91 |
|
real zlevinter(klon) |
92 |
|
|
93 |
|
EXTERNAL SCOPY |
94 |
|
|
95 |
|
!----------------------------------------------------------------------- |
96 |
|
|
97 |
|
! initialisation: |
98 |
|
|
99 |
|
IF(ngrid.NE.klon) THEN |
100 |
|
PRINT * |
101 |
|
PRINT *, 'STOP dans convadj' |
102 |
|
PRINT *, 'ngrid =', ngrid |
103 |
|
PRINT *, 'klon =', klon |
104 |
|
ENDIF |
105 |
|
|
106 |
|
! incrementation eventuelle de tendances precedentes: |
107 |
|
|
108 |
|
print *, '0 OK convect8' |
109 |
|
|
110 |
|
DO l=1, nlay |
111 |
|
DO ig=1, ngrid |
112 |
|
zpspsk(ig, l)=(pplay(ig, l)/pplev(ig, 1))**RKAPPA |
113 |
|
zh(ig, l)=pt(ig, l)/zpspsk(ig, l) |
114 |
|
zu(ig, l)=pu(ig, l) |
115 |
|
zv(ig, l)=pv(ig, l) |
116 |
|
zo(ig, l)=po(ig, l) |
117 |
|
ztv(ig, l)=zh(ig, l)*(1.+0.61*zo(ig, l)) |
118 |
|
end DO |
119 |
|
end DO |
120 |
|
|
121 |
|
print *, '1 OK convect8' |
122 |
|
|
123 |
|
! See notes, "thermcell.txt" |
124 |
|
! Calcul des altitudes des couches |
125 |
|
|
126 |
|
do l=2, nlay |
127 |
|
do ig=1, ngrid |
128 |
|
zlev(ig, l)=0.5*(pphi(ig, l)+pphi(ig, l-1))/RG |
129 |
|
enddo |
130 |
|
enddo |
131 |
|
do ig=1, ngrid |
132 |
|
zlev(ig, 1)=0. |
133 |
|
zlev(ig, nlay+1)=(2.*pphi(ig, klev)-pphi(ig, klev-1))/RG |
134 |
|
enddo |
135 |
|
|
136 |
|
! Calcul des densites |
137 |
|
|
138 |
|
do l=1, nlay |
139 |
|
do ig=1, ngrid |
140 |
|
rho(ig, l)=pplay(ig, l)/(zpspsk(ig, l)*RD*zh(ig, l)) |
141 |
|
enddo |
142 |
|
enddo |
143 |
|
|
144 |
|
do l=2, nlay |
145 |
|
do ig=1, ngrid |
146 |
|
rhobarz(ig, l)=0.5*(rho(ig, l)+rho(ig, l-1)) |
147 |
|
enddo |
148 |
|
enddo |
149 |
|
|
150 |
|
! Calcul de w2, quarre de w a partir de la cape |
151 |
|
! a partir de w2, on calcule wa, vitesse de l'ascendance |
152 |
|
|
153 |
|
! ATTENTION: Dans cette version, pour cause d'economie de memoire, |
154 |
|
! w2 est stoke dans wa |
155 |
|
|
156 |
|
! ATTENTION: dans convect8, on n'utilise le calcule des wa |
157 |
|
! independants par couches que pour calculer l'entrainement |
158 |
|
! a la base et la hauteur max de l'ascendance. |
159 |
|
|
160 |
|
! Indicages: |
161 |
|
! l'ascendance provenant du niveau k traverse l'interface l avec |
162 |
|
! une vitesse wa(k, l). |
163 |
|
! See notes, "thermcell.txt". |
164 |
|
|
165 |
|
!CR: ponderation entrainement des couches instables |
166 |
|
!def des entr_star tels que entr=f*entr_star |
167 |
|
do l=1, klev |
168 |
|
do ig=1, ngrid |
169 |
|
entr_star(ig, l)=0. |
170 |
|
enddo |
171 |
|
enddo |
172 |
|
! determination de la longueur de la couche d entrainement |
173 |
|
do ig=1, ngrid |
174 |
|
lentr(ig)=1 |
175 |
|
enddo |
176 |
|
|
177 |
|
!on ne considere que les premieres couches instables |
178 |
|
do k=nlay-2, 1, -1 |
179 |
|
do ig=1, ngrid |
180 |
|
if (ztv(ig, k).gt.ztv(ig, k+1).and. & |
181 |
|
ztv(ig, k+1).le.ztv(ig, k+2)) then |
182 |
|
lentr(ig)=k |
183 |
|
endif |
184 |
|
enddo |
185 |
|
enddo |
186 |
|
|
187 |
|
! determination du lmin: couche d ou provient le thermique |
188 |
|
do ig=1, ngrid |
189 |
|
lmin(ig)=1 |
190 |
|
enddo |
191 |
|
do ig=1, ngrid |
192 |
|
do l=nlay, 2, -1 |
193 |
|
if (ztv(ig, l-1).gt.ztv(ig, l)) then |
194 |
|
lmin(ig)=l-1 |
195 |
|
endif |
196 |
|
enddo |
197 |
|
enddo |
198 |
|
|
199 |
|
! definition de l'entrainement des couches |
200 |
|
do l=1, klev-1 |
201 |
|
do ig=1, ngrid |
202 |
|
if (ztv(ig, l).gt.ztv(ig, l+1).and. & |
203 |
|
l.ge.lmin(ig).and.l.le.lentr(ig)) then |
204 |
|
entr_star(ig, l)=(ztv(ig, l)-ztv(ig, l+1))* & |
205 |
|
(zlev(ig, l+1)-zlev(ig, l)) |
206 |
|
endif |
207 |
|
enddo |
208 |
|
enddo |
209 |
|
! pas de thermique si couches 1->5 stables |
210 |
|
do ig=1, ngrid |
211 |
|
if (lmin(ig).gt.5) then |
212 |
|
do l=1, klev |
213 |
|
entr_star(ig, l)=0. |
214 |
|
enddo |
215 |
|
endif |
216 |
|
enddo |
217 |
|
! calcul de l entrainement total |
218 |
|
do ig=1, ngrid |
219 |
|
entr_star_tot(ig)=0. |
220 |
|
enddo |
221 |
|
do ig=1, ngrid |
222 |
|
do k=1, klev |
223 |
|
entr_star_tot(ig)=entr_star_tot(ig)+entr_star(ig, k) |
224 |
|
enddo |
225 |
|
enddo |
226 |
|
|
227 |
|
print *, 'fin calcul entr_star' |
228 |
|
do k=1, klev |
229 |
|
do ig=1, ngrid |
230 |
|
ztva(ig, k)=ztv(ig, k) |
231 |
|
enddo |
232 |
|
enddo |
233 |
|
|
234 |
|
do k=1, klev+1 |
235 |
|
do ig=1, ngrid |
236 |
|
zw2(ig, k)=0. |
237 |
|
fmc(ig, k)=0. |
238 |
|
|
239 |
|
f_star(ig, k)=0. |
240 |
|
|
241 |
|
larg_cons(ig, k)=0. |
242 |
|
larg_detr(ig, k)=0. |
243 |
|
wa_moy(ig, k)=0. |
244 |
|
enddo |
245 |
|
enddo |
246 |
|
|
247 |
|
do ig=1, ngrid |
248 |
|
linter(ig)=1. |
249 |
|
lmaxa(ig)=1 |
250 |
|
lmix(ig)=1 |
251 |
|
wmaxa(ig)=0. |
252 |
|
enddo |
253 |
|
|
254 |
|
do l=1, nlay-2 |
255 |
|
do ig=1, ngrid |
256 |
|
if (ztv(ig, l).gt.ztv(ig, l+1) & |
257 |
|
.and.entr_star(ig, l).gt.1.e-10 & |
258 |
|
.and.zw2(ig, l).lt.1e-10) then |
259 |
|
f_star(ig, l+1)=entr_star(ig, l) |
260 |
|
!test:calcul de dteta |
261 |
|
zw2(ig, l+1)=2.*RG*(ztv(ig, l)-ztv(ig, l+1))/ztv(ig, l+1) & |
262 |
|
*(zlev(ig, l+1)-zlev(ig, l)) & |
263 |
|
*0.4*pphi(ig, l)/(pphi(ig, l+1)-pphi(ig, l)) |
264 |
|
larg_detr(ig, l)=0. |
265 |
|
else if ((zw2(ig, l).ge.1e-10).and. & |
266 |
|
(f_star(ig, l)+entr_star(ig, l).gt.1.e-10)) then |
267 |
|
f_star(ig, l+1)=f_star(ig, l)+entr_star(ig, l) |
268 |
|
ztva(ig, l)=(f_star(ig, l)*ztva(ig, l-1)+entr_star(ig, l) & |
269 |
|
*ztv(ig, l))/f_star(ig, l+1) |
270 |
|
zw2(ig, l+1)=zw2(ig, l)*(f_star(ig, l)/f_star(ig, l+1))**2+ & |
271 |
|
2.*RG*(ztva(ig, l)-ztv(ig, l))/ztv(ig, l) & |
272 |
|
*(zlev(ig, l+1)-zlev(ig, l)) |
273 |
|
endif |
274 |
|
! determination de zmax continu par interpolation lineaire |
275 |
|
if (zw2(ig, l+1).lt.0.) then |
276 |
|
if (abs(zw2(ig, l+1)-zw2(ig, l)).lt.1e-10) then |
277 |
|
print *, 'pb linter' |
278 |
|
endif |
279 |
|
linter(ig)=(l*(zw2(ig, l+1)-zw2(ig, l)) & |
280 |
|
-zw2(ig, l))/(zw2(ig, l+1)-zw2(ig, l)) |
281 |
|
zw2(ig, l+1)=0. |
282 |
|
lmaxa(ig)=l |
283 |
|
else |
284 |
|
if (zw2(ig, l+1).lt.0.) then |
285 |
|
print *, 'pb1 zw2<0' |
286 |
|
endif |
287 |
|
wa_moy(ig, l+1)=sqrt(zw2(ig, l+1)) |
288 |
|
endif |
289 |
|
if (wa_moy(ig, l+1).gt.wmaxa(ig)) then |
290 |
|
! lmix est le niveau de la couche ou w (wa_moy) est maximum |
291 |
|
lmix(ig)=l+1 |
292 |
|
wmaxa(ig)=wa_moy(ig, l+1) |
293 |
|
endif |
294 |
|
enddo |
295 |
|
enddo |
296 |
|
print *, 'fin calcul zw2' |
297 |
|
|
298 |
|
! Calcul de la couche correspondant a la hauteur du thermique |
299 |
|
do ig=1, ngrid |
300 |
|
lmax(ig)=lentr(ig) |
301 |
|
enddo |
302 |
|
do ig=1, ngrid |
303 |
|
do l=nlay, lentr(ig)+1, -1 |
304 |
|
if (zw2(ig, l).le.1.e-10) then |
305 |
|
lmax(ig)=l-1 |
306 |
|
endif |
307 |
|
enddo |
308 |
|
enddo |
309 |
|
! pas de thermique si couches 1->5 stables |
310 |
|
do ig=1, ngrid |
311 |
|
if (lmin(ig).gt.5) then |
312 |
|
lmax(ig)=1 |
313 |
|
lmin(ig)=1 |
314 |
|
endif |
315 |
|
enddo |
316 |
|
|
317 |
|
! Determination de zw2 max |
318 |
|
do ig=1, ngrid |
319 |
|
wmax(ig)=0. |
320 |
|
enddo |
321 |
|
|
322 |
|
do l=1, nlay |
323 |
|
do ig=1, ngrid |
324 |
|
if (l.le.lmax(ig)) then |
325 |
|
if (zw2(ig, l).lt.0.)then |
326 |
|
print *, 'pb2 zw2<0' |
327 |
|
endif |
328 |
|
zw2(ig, l)=sqrt(zw2(ig, l)) |
329 |
|
wmax(ig)=max(wmax(ig), zw2(ig, l)) |
330 |
|
else |
331 |
|
zw2(ig, l)=0. |
332 |
|
endif |
333 |
|
enddo |
334 |
|
enddo |
335 |
|
|
336 |
|
! Longueur caracteristique correspondant a la hauteur des thermiques. |
337 |
|
do ig=1, ngrid |
338 |
|
zmax(ig)=0. |
339 |
|
zlevinter(ig)=zlev(ig, 1) |
340 |
|
enddo |
341 |
|
do ig=1, ngrid |
342 |
|
! calcul de zlevinter |
343 |
|
zlevinter(ig)=(zlev(ig, lmax(ig)+1)-zlev(ig, lmax(ig)))* & |
344 |
|
linter(ig)+zlev(ig, lmax(ig))-lmax(ig)*(zlev(ig, lmax(ig)+1) & |
345 |
|
-zlev(ig, lmax(ig))) |
346 |
|
zmax(ig)=max(zmax(ig), zlevinter(ig)-zlev(ig, lmin(ig))) |
347 |
|
enddo |
348 |
|
|
349 |
|
print *, 'avant fermeture' |
350 |
|
! Fermeture, determination de f |
351 |
|
do ig=1, ngrid |
352 |
|
entr_star2(ig)=0. |
353 |
|
enddo |
354 |
|
do ig=1, ngrid |
355 |
|
if (entr_star_tot(ig).LT.1.e-10) then |
356 |
|
f(ig)=0. |
357 |
|
else |
358 |
|
do k=lmin(ig), lentr(ig) |
359 |
|
entr_star2(ig)=entr_star2(ig)+entr_star(ig, k)**2 & |
360 |
|
/(rho(ig, k)*(zlev(ig, k+1)-zlev(ig, k))) |
361 |
|
enddo |
362 |
|
! Nouvelle fermeture |
363 |
|
f(ig)=wmax(ig)/(max(500., zmax(ig))*r_aspect & |
364 |
|
*entr_star2(ig))*entr_star_tot(ig) |
365 |
|
endif |
366 |
|
enddo |
367 |
|
print *, 'apres fermeture' |
368 |
|
|
369 |
|
! Calcul de l'entrainement |
370 |
|
do k=1, klev |
371 |
|
do ig=1, ngrid |
372 |
|
entr(ig, k)=f(ig)*entr_star(ig, k) |
373 |
|
enddo |
374 |
|
enddo |
375 |
|
! Calcul des flux |
376 |
|
do ig=1, ngrid |
377 |
|
do l=1, lmax(ig)-1 |
378 |
|
fmc(ig, l+1)=fmc(ig, l)+entr(ig, l) |
379 |
|
enddo |
380 |
|
enddo |
381 |
|
|
382 |
|
! determination de l'indice du debut de la mixed layer ou w decroit |
383 |
|
|
384 |
|
! calcul de la largeur de chaque ascendance dans le cas conservatif. |
385 |
|
! dans ce cas simple, on suppose que la largeur de l'ascendance provenant |
386 |
|
! d'une couche est \'egale \`a la hauteur de la couche alimentante. |
387 |
|
! La vitesse maximale dans l'ascendance est aussi prise comme estimation |
388 |
|
! de la vitesse d'entrainement horizontal dans la couche alimentante. |
389 |
|
|
390 |
|
do l=2, nlay |
391 |
|
do ig=1, ngrid |
392 |
|
if (l.le.lmaxa(ig)) then |
393 |
|
zw=max(wa_moy(ig, l), 1.e-10) |
394 |
|
larg_cons(ig, l)=zmax(ig)*r_aspect & |
395 |
|
*fmc(ig, l)/(rhobarz(ig, l)*zw) |
396 |
|
endif |
397 |
|
enddo |
398 |
|
enddo |
399 |
|
|
400 |
|
do l=2, nlay |
401 |
|
do ig=1, ngrid |
402 |
|
if (l.le.lmaxa(ig)) then |
403 |
|
if ((l_mix*zlev(ig, l)).lt.0.)then |
404 |
|
print *, 'pb l_mix*zlev<0' |
405 |
|
endif |
406 |
|
larg_detr(ig, l)=sqrt(l_mix*zlev(ig, l)) |
407 |
|
endif |
408 |
|
enddo |
409 |
|
enddo |
410 |
|
|
411 |
|
! calcul de la fraction de la maille concern\'ee par l'ascendance en tenant |
412 |
|
! compte de l'epluchage du thermique. |
413 |
|
|
414 |
|
!CR def de zmix continu (profil parabolique des vitesses) |
415 |
|
do ig=1, ngrid |
416 |
|
if (lmix(ig).gt.1.) then |
417 |
|
if (((zw2(ig, lmix(ig)-1)-zw2(ig, lmix(ig))) & |
418 |
|
*((zlev(ig, lmix(ig)))-(zlev(ig, lmix(ig)+1))) & |
419 |
|
-(zw2(ig, lmix(ig))-zw2(ig, lmix(ig)+1)) & |
420 |
|
*((zlev(ig, lmix(ig)-1))-(zlev(ig, lmix(ig))))).gt.1e-10) & |
421 |
|
then |
422 |
|
|
423 |
|
zmix(ig)=((zw2(ig, lmix(ig)-1)-zw2(ig, lmix(ig))) & |
424 |
|
*((zlev(ig, lmix(ig)))**2-(zlev(ig, lmix(ig)+1))**2) & |
425 |
|
-(zw2(ig, lmix(ig))-zw2(ig, lmix(ig)+1)) & |
426 |
|
*((zlev(ig, lmix(ig)-1))**2-(zlev(ig, lmix(ig)))**2)) & |
427 |
|
/(2.*((zw2(ig, lmix(ig)-1)-zw2(ig, lmix(ig))) & |
428 |
|
*((zlev(ig, lmix(ig)))-(zlev(ig, lmix(ig)+1))) & |
429 |
|
-(zw2(ig, lmix(ig))-zw2(ig, lmix(ig)+1)) & |
430 |
|
*((zlev(ig, lmix(ig)-1))-(zlev(ig, lmix(ig)))))) |
431 |
|
else |
432 |
|
zmix(ig)=zlev(ig, lmix(ig)) |
433 |
|
print *, 'pb zmix' |
434 |
|
endif |
435 |
|
else |
436 |
|
zmix(ig)=0. |
437 |
|
endif |
438 |
|
|
439 |
|
if ((zmax(ig)-zmix(ig)).lt.0.) then |
440 |
|
zmix(ig)=0.99*zmax(ig) |
441 |
|
endif |
442 |
|
enddo |
443 |
|
|
444 |
|
! calcul du nouveau lmix correspondant |
445 |
|
do ig=1, ngrid |
446 |
|
do l=1, klev |
447 |
|
if (zmix(ig).ge.zlev(ig, l).and. & |
448 |
|
zmix(ig).lt.zlev(ig, l+1)) then |
449 |
|
lmix(ig)=l |
450 |
|
endif |
451 |
|
enddo |
452 |
|
enddo |
453 |
|
|
454 |
|
do l=2, nlay |
455 |
|
do ig=1, ngrid |
456 |
|
if(larg_cons(ig, l).gt.1.) then |
457 |
|
fraca(ig, l)=(larg_cons(ig, l)-larg_detr(ig, l)) & |
458 |
|
/(r_aspect*zmax(ig)) |
459 |
|
fraca(ig, l)=max(fraca(ig, l), 0.) |
460 |
|
fraca(ig, l)=min(fraca(ig, l), 0.5) |
461 |
|
fracd(ig, l)=1.-fraca(ig, l) |
462 |
|
fracc(ig, l)=larg_cons(ig, l)/(r_aspect*zmax(ig)) |
463 |
|
else |
464 |
|
fraca(ig, l)=0. |
465 |
|
fracc(ig, l)=0. |
466 |
|
fracd(ig, l)=1. |
467 |
|
endif |
468 |
|
enddo |
469 |
|
enddo |
470 |
|
!CR: calcul de fracazmix |
471 |
|
do ig=1, ngrid |
472 |
|
fracazmix(ig)=(fraca(ig, lmix(ig)+1)-fraca(ig, lmix(ig)))/ & |
473 |
|
(zlev(ig, lmix(ig)+1)-zlev(ig, lmix(ig)))*zmix(ig) & |
474 |
|
+fraca(ig, lmix(ig))-zlev(ig, lmix(ig))*(fraca(ig, lmix(ig)+1) & |
475 |
|
-fraca(ig, lmix(ig)))/(zlev(ig, lmix(ig)+1)-zlev(ig, lmix(ig))) |
476 |
|
enddo |
477 |
|
|
478 |
|
do l=2, nlay |
479 |
|
do ig=1, ngrid |
480 |
|
if(larg_cons(ig, l).gt.1.) then |
481 |
|
if (l.gt.lmix(ig)) then |
482 |
|
if (zmax(ig)-zmix(ig).lt.1.e-10) then |
483 |
|
xxx(ig, l)=(lmaxa(ig)+1.-l)/(lmaxa(ig)+1.-lmix(ig)) |
484 |
|
else |
485 |
|
xxx(ig, l)=(zmax(ig)-zlev(ig, l))/(zmax(ig)-zmix(ig)) |
486 |
|
endif |
487 |
|
if (idetr.eq.0) then |
488 |
|
fraca(ig, l)=fracazmix(ig) |
489 |
|
else if (idetr.eq.1) then |
490 |
|
fraca(ig, l)=fracazmix(ig)*xxx(ig, l) |
491 |
|
else if (idetr.eq.2) then |
492 |
|
fraca(ig, l)=fracazmix(ig)*(1.-(1.-xxx(ig, l))**2) |
493 |
|
else |
494 |
|
fraca(ig, l)=fracazmix(ig)*xxx(ig, l)**2 |
495 |
|
endif |
496 |
|
fraca(ig, l)=max(fraca(ig, l), 0.) |
497 |
|
fraca(ig, l)=min(fraca(ig, l), 0.5) |
498 |
|
fracd(ig, l)=1.-fraca(ig, l) |
499 |
|
fracc(ig, l)=larg_cons(ig, l)/(r_aspect*zmax(ig)) |
500 |
|
endif |
501 |
|
endif |
502 |
|
enddo |
503 |
|
enddo |
504 |
|
|
505 |
|
print *, 'fin calcul fraca' |
506 |
|
|
507 |
|
! Calcul de fracd, wd |
508 |
|
! somme wa - wd = 0 |
509 |
|
|
510 |
|
do ig=1, ngrid |
511 |
|
fm(ig, 1)=0. |
512 |
|
fm(ig, nlay+1)=0. |
513 |
|
enddo |
514 |
|
|
515 |
|
do l=2, nlay |
516 |
|
do ig=1, ngrid |
517 |
|
fm(ig, l)=fraca(ig, l)*wa_moy(ig, l)*rhobarz(ig, l) |
518 |
|
if (entr(ig, l-1).lt.1e-10.and.fm(ig, l).gt.fm(ig, l-1) & |
519 |
|
.and.l.gt.lmix(ig)) then |
520 |
|
fm(ig, l)=fm(ig, l-1) |
521 |
|
endif |
522 |
|
enddo |
523 |
|
do ig=1, ngrid |
524 |
|
if(fracd(ig, l).lt.0.1) then |
525 |
|
stop'fracd trop petit' |
526 |
|
endif |
527 |
|
enddo |
528 |
|
enddo |
529 |
|
|
530 |
|
do l=1, nlay |
531 |
|
do ig=1, ngrid |
532 |
|
masse(ig, l)=(pplev(ig, l)-pplev(ig, l+1))/RG |
533 |
|
enddo |
534 |
|
enddo |
535 |
|
|
536 |
|
print *, '12 OK convect8' |
537 |
|
|
538 |
|
! calcul du transport vertical |
539 |
|
|
540 |
|
!CR:redefinition du entr |
541 |
|
do l=1, nlay |
542 |
|
do ig=1, ngrid |
543 |
|
detr(ig, l)=fm(ig, l)+entr(ig, l)-fm(ig, l+1) |
544 |
|
if (detr(ig, l).lt.0.) then |
545 |
|
entr(ig, l)=entr(ig, l)-detr(ig, l) |
546 |
|
detr(ig, l)=0. |
547 |
|
endif |
548 |
|
enddo |
549 |
|
enddo |
550 |
|
|
551 |
|
if (w2di.eq.1) then |
552 |
|
fm0=fm0+ptimestep*(fm-fm0)/tho |
553 |
|
entr0=entr0+ptimestep*(entr-entr0)/tho |
554 |
|
else |
555 |
|
fm0=fm |
556 |
|
entr0=entr |
557 |
|
endif |
558 |
|
|
559 |
|
if (1.eq.1) then |
560 |
|
call dqthermcell(ngrid, nlay, ptimestep, fm0, entr0, masse & |
561 |
|
, zh, zdhadj, zha) |
562 |
|
call dqthermcell(ngrid, nlay, ptimestep, fm0, entr0, masse & |
563 |
|
, zo, pdoadj, zoa) |
564 |
|
else |
565 |
|
call dqthermcell2(ngrid, nlay, ptimestep, fm0, entr0, masse, fraca & |
566 |
|
, zh, zdhadj, zha) |
567 |
|
call dqthermcell2(ngrid, nlay, ptimestep, fm0, entr0, masse, fraca & |
568 |
|
, zo, pdoadj, zoa) |
569 |
|
endif |
570 |
|
|
571 |
|
if (1.eq.0) then |
572 |
|
call dvthermcell2(ngrid, nlay, ptimestep, fm0, entr0, masse & |
573 |
|
, fraca, zmax & |
574 |
|
, zu, zv, pduadj, pdvadj, zua, zva) |
575 |
|
else |
576 |
|
call dqthermcell(ngrid, nlay, ptimestep, fm0, entr0, masse & |
577 |
|
, zu, pduadj, zua) |
578 |
|
call dqthermcell(ngrid, nlay, ptimestep, fm0, entr0, masse & |
579 |
|
, zv, pdvadj, zva) |
580 |
|
endif |
581 |
|
|
582 |
|
do l=1, nlay |
583 |
|
do ig=1, ngrid |
584 |
|
zf=0.5*(fracc(ig, l)+fracc(ig, l+1)) |
585 |
|
zf2=zf/(1.-zf) |
586 |
|
thetath2(ig, l)=zf2*(zha(ig, l)-zh(ig, l))**2 |
587 |
|
wth2(ig, l)=zf2*(0.5*(wa_moy(ig, l)+wa_moy(ig, l+1)))**2 |
588 |
|
enddo |
589 |
|
enddo |
590 |
|
|
591 |
|
do l=1, nlay |
592 |
|
do ig=1, ngrid |
593 |
|
pdtadj(ig, l)=zdhadj(ig, l)*zpspsk(ig, l) |
594 |
|
enddo |
595 |
|
enddo |
596 |
|
|
597 |
print *, '19 OK convect8' |
end SUBROUTINE thermcell |
598 |
|
|
599 |
end SUBROUTINE thermcell |
end module thermcell_m |