! $Header$ SUBROUTINE yamada_c(ngrid,timestep,plev,play & ,pu,pv,pt,d_u,d_v,d_t,cd,q2,km,kn,kq,d_t_diss,ustar & ,iflag_pbl) USE dimphy, ONLY: klon, klev USE lmdz_print_control, ONLY: prt_level USE lmdz_ioipsl_getin_p, ONLY: getin_p IMPLICIT NONE INCLUDE "YOMCST.h" ! timestep : pas de temps ! g : g ! zlev : altitude a chaque niveau (interface inferieure de la couche ! de meme indice) ! zlay : altitude au centre de chaque couche ! u,v : vitesse au centre de chaque couche ! (en entree : la valeur au debut du pas de temps) ! teta : temperature potentielle au centre de chaque couche ! (en entree : la valeur au debut du pas de temps) ! cd : cdrag ! (en entree : la valeur au debut du pas de temps) ! q2 : $q^2$ au bas de chaque couche ! (en entree : la valeur au debut du pas de temps) ! (en sortie : la valeur a la fin du pas de temps) ! km : diffusivite turbulente de quantite de mouvement (au bas de chaque ! couche) ! (en sortie : la valeur a la fin du pas de temps) ! kn : diffusivite turbulente des scalaires (au bas de chaque couche) ! (en sortie : la valeur a la fin du pas de temps) ! iflag_pbl doit valoir entre 6 et 9 ! l=6, on prend systematiquement une longueur d'equilibre ! iflag_pbl=6 : MY 2.0 ! iflag_pbl=7 : MY 2.0.Fournier ! iflag_pbl=8/9 : MY 2.5 ! iflag_pbl=8 with special obsolete treatments for convergence ! with Cmpi5 NPv3.1 simulations ! iflag_pbl=10/11 : New scheme M2 and N2 explicit and dissiptation exact ! iflag_pbl=12 = 11 with vertical diffusion off q2 ! 2013/04/01 (FH hourdin@lmd.jussieu.fr) ! Correction for very stable PBLs (iflag_pbl=10 and 11) ! iflag_pbl=8 converges numerically with NPv3.1 ! iflag_pbl=11 -> the model starts with NP from start files created by ce0l ! -> the model can run with longer time-steps. !....................................................................... REAL, DIMENSION(klon,klev) :: d_u,d_v,d_t REAL, DIMENSION(klon,klev) :: pu,pv,pt REAL, DIMENSION(klon,klev) :: d_t_diss REAL timestep real plev(klon,klev+1) real play(klon,klev) real ustar(klon) real kmin,qmin,pblhmin(klon),coriol(klon) REAL zlev(klon,klev+1) REAL zlay(klon,klev) REAL zu(klon,klev) REAL zv(klon,klev) REAL zt(klon,klev) REAL teta(klon,klev) REAL cd(klon) REAL q2(klon,klev+1),qpre REAL unsdz(klon,klev) REAL unsdzdec(klon,klev+1) REAL km(klon,klev) REAL kmpre(klon,klev+1),tmp2 REAL mpre(klon,klev+1) REAL kn(klon,klev) REAL kq(klon,klev) real ff(klon,klev+1),delta(klon,klev+1) real aa(klon,klev+1),aa0,aa1 integer iflag_pbl,ngrid integer nlay,nlev logical first integer ipas save first,ipas !FH/IM data first,ipas/.TRUE.,0/ data first,ipas/.FALSE.,0/ !$OMP THREADPRIVATE( first,ipas) INTEGER, SAVE :: iflag_tke_diff=0 !$OMP THREADPRIVATE(iflag_tke_diff) integer ig,k real ri,zrif,zalpha,zsm,zsn real rif(klon,klev+1),sm(klon,klev+1),alpha(klon,klev) real m2(klon,klev+1),dz(klon,klev+1),zq,n2(klon,klev+1) REAL, DIMENSION(klon,klev+1) :: km2,kn2,sqrtq real dtetadz(klon,klev+1) real m2cstat,mcstat,kmcstat real l(klon,klev+1) real leff(klon,klev+1) real,allocatable,save :: l0(:) !$OMP THREADPRIVATE(l0) real sq(klon),sqz(klon),zz(klon,klev+1) integer iter real ric,rifc,b1,kap save ric,rifc,b1,kap data ric,rifc,b1,kap/0.195,0.191,16.6,0.4/ !$OMP THREADPRIVATE(ric,rifc,b1,kap) real frif,falpha,fsm real fl,zzz,zl0,zq2,zn2 real rino(klon,klev+1),smyam(klon,klev),styam(klon,klev) real lyam(klon,klev),knyam(klon,klev) real w2yam(klon,klev),t2yam(klon,klev) logical,save :: firstcall=.TRUE. !$OMP THREADPRIVATE(firstcall) CHARACTER(len=20),PARAMETER :: modname="yamada_c" REAL, DIMENSION(klon,klev+1) :: fluxu,fluxv,fluxt REAL, DIMENSION(klon,klev+1) :: dddu,dddv,dddt REAL, DIMENSION(klon,klev) :: exner,masse REAL, DIMENSION(klon,klev+1) :: masseb,q2old,q2neg LOGICAL okiophys frif(ri)=0.6588*(ri+0.1776-sqrt(ri*ri-0.3221*ri+0.03156)) falpha(ri)=1.318*(0.2231-ri)/(0.2341-ri) fsm(ri)=1.96*(0.1912-ri)*(0.2341-ri)/((1.-ri)*(0.2231-ri)) fl(zzz,zl0,zq2,zn2)= & max(min(l0(ig)*kap*zlev(ig,k)/(kap*zlev(ig,k)+l0(ig)) & ,0.5*sqrt(q2(ig,k))/sqrt(max(n2(ig,k),1.e-10))) ,1.) okiophys=klon==1 if (firstcall) THEN CALL getin_p('iflag_tke_diff',iflag_tke_diff) allocate(l0(klon)) #define IOPHYS #ifdef IOPHYS ! CALL iophys_ini(timestep) #endif firstcall=.FALSE. endif IF (ngrid<=0) RETURN ! Bizarre : on n a pas ce probeleme pour coef_diff_turb #ifdef IOPHYS IF (okiophys) THEN CALL iophys_ecrit('q2i',klev,'q2 debut my','m2/s2',q2(:,1:klev)) CALL iophys_ecrit('kmi',klev,'Kz debut my','m/s2',km(:,1:klev)) END IF #endif nlay=klev nlev=klev+1 !------------------------------------------------------------------------- ! Computation of conservative source terms from the turbulent tendencies !------------------------------------------------------------------------- zalpha=0.5 ! Anciennement 0.5. Essayer de voir pourquoi ? zu(:,:)=pu(:,:)+zalpha*d_u(:,:) zv(:,:)=pv(:,:)+zalpha*d_v(:,:) zt(:,:)=pt(:,:)+zalpha*d_t(:,:) do k=1,klev exner(:,k)=(play(:,k)/plev(:,1))**RKAPPA masse(:,k)=(plev(:,k)-plev(:,k+1))/RG teta(:,k)=zt(:,k)/exner(:,k) enddo ! Atmospheric mass at layer interfaces, where the TKE is computed masseb(:,:)=0. do k=1,klev masseb(:,k)=masseb(:,k)+masse(:,k) masseb(:,k+1)=masseb(:,k+1)+masse(:,k) enddo masseb(:,:)=0.5*masseb(:,:) zlev(:,1)=0. zlay(:,1)=RCPD*teta(:,1)*(1.-exner(:,1)) do k=1,klev-1 zlay(:,k+1)=zlay(:,k)+0.5*RCPD*(teta(:,k)+teta(:,k+1))*(exner(:,k)-exner(:,k+1))/RG zlev(:,k)=0.5*(zlay(:,k)+zlay(:,k+1)) ! PASBO enddo fluxu(:,klev+1)=0. fluxv(:,klev+1)=0. fluxt(:,klev+1)=0. do k=klev,1,-1 fluxu(:,k)=fluxu(:,k+1)+masse(:,k)*d_u(:,k) fluxv(:,k)=fluxv(:,k+1)+masse(:,k)*d_v(:,k) fluxt(:,k)=fluxt(:,k+1)+masse(:,k)*d_t(:,k)/exner(:,k) ! Flux de theta enddo dddu(:,1)=2*zu(:,1)*fluxu(:,1) dddv(:,1)=2*zv(:,1)*fluxv(:,1) dddt(:,1)=(exner(:,1)-1.)*fluxt(:,1) do k=2,klev dddu(:,k)=(zu(:,k)-zu(:,k-1))*fluxu(:,k) dddv(:,k)=(zv(:,k)-zv(:,k-1))*fluxv(:,k) dddt(:,k)=(exner(:,k)-exner(:,k-1))*fluxt(:,k) enddo dddu(:,klev+1)=0. dddv(:,klev+1)=0. dddt(:,klev+1)=0. #ifdef IOPHYS IF (okiophys) THEN CALL iophys_ecrit('zlay',klev,'Geop','m',zlay) CALL iophys_ecrit('teta',klev,'teta','K',teta) CALL iophys_ecrit('temp',klev,'temp','K',zt) CALL iophys_ecrit('pt',klev,'temp','K',pt) CALL iophys_ecrit('pu',klev,'u','m/s',pu) CALL iophys_ecrit('pv',klev,'v','m/s',pv) CALL iophys_ecrit('d_u',klev,'d_u','m/s2',d_u) CALL iophys_ecrit('d_v',klev,'d_v','m/s2',d_v) CALL iophys_ecrit('d_t',klev,'d_t','K/s',d_t) CALL iophys_ecrit('exner',klev,'exner','',exner) CALL iophys_ecrit('masse',klev,'masse','',masse) CALL iophys_ecrit('masseb',klev,'masseb','',masseb) END IF #endif ipas=ipas+1 !....................................................................... ! les increments verticaux !....................................................................... !!!!!! allerte !!!!!c !!!!!! zlev n'est pas declare a nlev !!!!!c !!!!!! ----> DO ig=1,ngrid zlev(ig,nlev)=zlay(ig,nlay) & +( zlay(ig,nlay) - zlev(ig,nlev-1) ) ENDDO !!!!!! <---- !!!!!! allerte !!!!!c DO k=1,nlay DO ig=1,ngrid unsdz(ig,k)=1.E+0/(zlev(ig,k+1)-zlev(ig,k)) ENDDO ENDDO DO ig=1,ngrid unsdzdec(ig,1)=1.E+0/(zlay(ig,1)-zlev(ig,1)) ENDDO DO k=2,nlay DO ig=1,ngrid unsdzdec(ig,k)=1.E+0/(zlay(ig,k)-zlay(ig,k-1)) ENDDO ENDDO DO ig=1,ngrid unsdzdec(ig,nlay+1)=1.E+0/(zlev(ig,nlay+1)-zlay(ig,nlay)) ENDDO !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! Computing M^2, N^2, Richardson numbers, stability functions !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! do k=2,klev do ig=1,ngrid dz(ig,k)=zlay(ig,k)-zlay(ig,k-1) m2(ig,k)=((zu(ig,k)-zu(ig,k-1))**2+(zv(ig,k)-zv(ig,k-1))**2)/(dz(ig,k)*dz(ig,k)) dtetadz(ig,k)=(teta(ig,k)-teta(ig,k-1))/dz(ig,k) n2(ig,k)=RG*2.*dtetadz(ig,k)/(teta(ig,k-1)+teta(ig,k)) ! n2(ig,k)=0. ri=n2(ig,k)/max(m2(ig,k),1.e-10) if (ri