! $Header$ SUBROUTINE yamada4(ngrid, dt, g, rconst, plev, temp, zlev, zlay, u, v, teta, & cd, q2, km, kn, kq, ustar, iflag_pbl) USE dimphy IMPLICIT NONE include "iniprint.h" ! ....................................................................... ! ym#include "dimensions.h" ! ym#include "dimphy.h" ! ....................................................................... ! dt : 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 dt, g, rconst REAL plev(klon, klev+1), temp(klon, klev) REAL ustar(klon) REAL kmin, qmin, pblhmin(klon), coriol(klon) REAL zlev(klon, klev+1) REAL zlay(klon, klev) REAL u(klon, klev) REAL v(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+1) REAL kmpre(klon, klev+1), tmp2 REAL mpre(klon, klev+1) REAL kn(klon, klev+1) REAL kq(klon, klev+1) 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 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 dtetadz(klon, klev+1) REAL m2cstat, mcstat, kmcstat REAL l(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), & lyam(klon, klev), knyam(klon, klev), w2yam(klon, klev), t2yam(klon, klev) LOGICAL, SAVE :: firstcall = .TRUE. !$OMP THREADPRIVATE(firstcall) 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.) nlay = klev nlev = klev + 1 IF (firstcall) THEN ALLOCATE (l0(klon)) firstcall = .FALSE. END IF IF (.NOT. (iflag_pbl>=6 .AND. iflag_pbl<=12)) THEN STOP 'probleme de coherence dans appel a MY' END IF 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)) END DO ! !!!!! <---- ! !!!!! allerte !!!!!c DO k = 1, nlay DO ig = 1, ngrid unsdz(ig, k) = 1.E+0/(zlev(ig,k+1)-zlev(ig,k)) END DO END DO DO ig = 1, ngrid unsdzdec(ig, 1) = 1.E+0/(zlay(ig,1)-zlev(ig,1)) END DO DO k = 2, nlay DO ig = 1, ngrid unsdzdec(ig, k) = 1.E+0/(zlay(ig,k)-zlay(ig,k-1)) END DO END DO DO ig = 1, ngrid unsdzdec(ig, nlay+1) = 1.E+0/(zlev(ig,nlay+1)-zlay(ig,nlay)) END DO ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! Computing M^2, N^2, Richardson numbers, stability functions ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! initialize arrays: m2(:, :) = 0.0 sm(:, :) = 0.0 rif(:, :) = 0.0 DO k = 2, klev DO ig = 1, ngrid dz(ig, k) = zlay(ig, k) - zlay(ig, k-1) m2(ig, k) = ((u(ig,k)-u(ig,k-1))**2+(v(ig,k)-v(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) = g*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 (ri1) THEN PRINT *, 'YAMADA4 0' END IF !(prt_level>1) THEN DO ig = 1, ngrid coriol(ig) = 1.E-4 pblhmin(ig) = 0.07*ustar(ig)/max(abs(coriol(ig)), 2.546E-5) END DO ! print*,'pblhmin ',pblhmin ! Test a remettre 21 11 02 ! test abd 13 05 02 if(0.eq.1) then IF (1==1) THEN IF (iflag_pbl==8 .OR. iflag_pbl==10) THEN DO k = 2, klev DO ig = 1, ngrid IF (teta(ig,2)>teta(ig,1)) THEN qmin = ustar(ig)*(max(1.-zlev(ig,k)/pblhmin(ig),0.))**2 kmin = kap*zlev(ig, k)*qmin ELSE kmin = -1. ! kmin n'est utilise que pour les SL stables. END IF IF (kn(ig,k)teta(ig,1)) THEN qmin = ustar(ig)*(max(1.-zlev(ig,k)/pblhmin(ig),0.))**2 kmin = kap*zlev(ig, k)*qmin ELSE kmin = -1. ! kmin n'est utilise que pour les SL stables. END IF IF (kn(ig,k)1) THEN PRINT *, 'YAMADA4 1' END IF !(prt_level>1) THEN ! Diagnostique pour stokage IF (1==0) THEN rino = rif smyam(1:ngrid, 1) = 0. styam(1:ngrid, 1) = 0. lyam(1:ngrid, 1) = 0. knyam(1:ngrid, 1) = 0. w2yam(1:ngrid, 1) = 0. t2yam(1:ngrid, 1) = 0. smyam(1:ngrid, 2:klev) = sm(1:ngrid, 2:klev) styam(1:ngrid, 2:klev) = sm(1:ngrid, 2:klev)*alpha(1:ngrid, 2:klev) lyam(1:ngrid, 2:klev) = l(1:ngrid, 2:klev) knyam(1:ngrid, 2:klev) = kn(1:ngrid, 2:klev) ! Estimations de w'2 et T'2 d'apres Abdela et McFarlane w2yam(1:ngrid, 2:klev) = q2(1:ngrid, 2:klev)*0.24 + & lyam(1:ngrid, 2:klev)*5.17*kn(1:ngrid, 2:klev)*n2(1:ngrid, 2:klev)/ & sqrt(q2(1:ngrid,2:klev)) t2yam(1:ngrid, 2:klev) = 9.1*kn(1:ngrid, 2:klev)* & dtetadz(1:ngrid, 2:klev)**2/sqrt(q2(1:ngrid,2:klev))* & lyam(1:ngrid, 2:klev) END IF ! print*,'OKFIN' first = .FALSE. RETURN END SUBROUTINE yamada4 SUBROUTINE vdif_q2(timestep, gravity, rconst, ngrid, plev, temp, kmy, q2) USE dimphy IMPLICIT NONE ! ....................................................................... include "dimensions.h" ! ccc#include "dimphy.h" ! ....................................................................... ! dt : pas de temps REAL plev(klon, klev+1) REAL temp(klon, klev) REAL timestep REAL gravity, rconst REAL kstar(klon, klev+1), zz REAL kmy(klon, klev+1) REAL q2(klon, klev+1) REAL deltap(klon, klev+1) REAL denom(klon, klev+1), alpha(klon, klev+1), beta(klon, klev+1) INTEGER ngrid INTEGER i, k ! print*,'RD=',rconst DO k = 1, klev DO i = 1, ngrid ! test ! print*,'i,k',i,k ! print*,'temp(i,k)=',temp(i,k) ! print*,'(plev(i,k)-plev(i,k+1))=',plev(i,k),plev(i,k+1) zz = (plev(i,k)+plev(i,k+1))*gravity/(rconst*temp(i,k)) kstar(i, k) = 0.125*(kmy(i,k+1)+kmy(i,k))*zz*zz/ & (plev(i,k)-plev(i,k+1))*timestep END DO END DO DO k = 2, klev DO i = 1, ngrid deltap(i, k) = 0.5*(plev(i,k-1)-plev(i,k+1)) END DO END DO DO i = 1, ngrid deltap(i, 1) = 0.5*(plev(i,1)-plev(i,2)) deltap(i, klev+1) = 0.5*(plev(i,klev)-plev(i,klev+1)) denom(i, klev+1) = deltap(i, klev+1) + kstar(i, klev) alpha(i, klev+1) = deltap(i, klev+1)*q2(i, klev+1)/denom(i, klev+1) beta(i, klev+1) = kstar(i, klev)/denom(i, klev+1) END DO DO k = klev, 2, -1 DO i = 1, ngrid denom(i, k) = deltap(i, k) + (1.-beta(i,k+1))*kstar(i, k) + & kstar(i, k-1) ! correction d'un bug 10 01 2001 alpha(i, k) = (q2(i,k)*deltap(i,k)+kstar(i,k)*alpha(i,k+1))/denom(i, k) beta(i, k) = kstar(i, k-1)/denom(i, k) END DO END DO ! Si on recalcule q2(1) IF (1==0) THEN DO i = 1, ngrid denom(i, 1) = deltap(i, 1) + (1-beta(i,2))*kstar(i, 1) q2(i, 1) = (q2(i,1)*deltap(i,1)+kstar(i,1)*alpha(i,2))/denom(i, 1) END DO END IF ! sinon, on peut sauter cette boucle... DO k = 2, klev + 1 DO i = 1, ngrid q2(i, k) = alpha(i, k) + beta(i, k)*q2(i, k-1) END DO END DO RETURN END SUBROUTINE vdif_q2 SUBROUTINE vdif_q2e(timestep, gravity, rconst, ngrid, plev, temp, kmy, q2) USE dimphy IMPLICIT NONE ! ....................................................................... include "dimensions.h" ! ccc#include "dimphy.h" ! ....................................................................... ! dt : pas de temps REAL plev(klon, klev+1) REAL temp(klon, klev) REAL timestep REAL gravity, rconst REAL kstar(klon, klev+1), zz REAL kmy(klon, klev+1) REAL q2(klon, klev+1) REAL deltap(klon, klev+1) REAL denom(klon, klev+1), alpha(klon, klev+1), beta(klon, klev+1) INTEGER ngrid INTEGER i, k DO k = 1, klev DO i = 1, ngrid zz = (plev(i,k)+plev(i,k+1))*gravity/(rconst*temp(i,k)) kstar(i, k) = 0.125*(kmy(i,k+1)+kmy(i,k))*zz*zz/ & (plev(i,k)-plev(i,k+1))*timestep END DO END DO DO k = 2, klev DO i = 1, ngrid deltap(i, k) = 0.5*(plev(i,k-1)-plev(i,k+1)) END DO END DO DO i = 1, ngrid deltap(i, 1) = 0.5*(plev(i,1)-plev(i,2)) deltap(i, klev+1) = 0.5*(plev(i,klev)-plev(i,klev+1)) END DO DO k = klev, 2, -1 DO i = 1, ngrid q2(i, k) = q2(i, k) + (kstar(i,k)*(q2(i,k+1)-q2(i, & k))-kstar(i,k-1)*(q2(i,k)-q2(i,k-1)))/deltap(i, k) END DO END DO DO i = 1, ngrid q2(i, 1) = q2(i, 1) + (kstar(i,1)*(q2(i,2)-q2(i,1)))/deltap(i, 1) q2(i, klev+1) = q2(i, klev+1) + (-kstar(i,klev)*(q2(i,klev+1)-q2(i, & klev)))/deltap(i, klev+1) END DO RETURN END SUBROUTINE vdif_q2e