! ! $Header$ ! c c subroutine read_reanalyse(timestep,psi s ,u,v,t,q,masse,ps,mode,nlevnc) c mode=0 variables naturelles c mode=1 variabels GCM c ----------------------------------------------------------------- c Declarations c ----------------------------------------------------------------- IMPLICIT NONE c common c ------ #include "netcdf.inc" #include "dimensions.h" #include "paramet.h" #include "comgeom.h" #include "comvert.h" #include "guide.h" c arguments c --------- integer nlevnc integer timestep,mode,l real psi(iip1,jjp1) real u(iip1,jjp1,llm),v(iip1,jjm,llm) real t(iip1,jjp1,llm),ps(iip1,jjp1),q(iip1,jjp1,llm) real masse(iip1,jjp1,llm),pk(iip1,jjp1,llm) c local c ----- integer ncidu,varidu,ncidv,varidv,ncidt,varidt,ncidps,varidps integer ncidpl integer varidpl,ncidQ,varidQ save ncidu,varidu,ncidv,varidv,ncidt,varidt,ncidps,varidps save ncidpl save varidpl,ncidQ,varidQ real*4 unc(iip1,jjp1,nlevnc),vnc(iip1,jjm,nlevnc) real*4 tnc(iip1,jjp1,nlevnc),psnc(iip1,jjp1) real*4 Qnc(iip1,jjp1,nlevnc) real*4 pl(nlevnc) integer start(4),count(4),status real rcode logical first save first data first/.true./ c ----------------------------------------------------------------- c Initialisation de la lecture des fichiers c ----------------------------------------------------------------- if (first) then ncidpl=-99 print*,'Intitialisation de read reanalsye' c Vent zonal if (guide_u) then ncidu=NCOPN('u.nc',NCNOWRIT,rcode) varidu=NCVID(ncidu,'UWND',rcode) print*,'ncidu,varidu',ncidu,varidu if (ncidpl.eq.-99) ncidpl=ncidu endif c Vent meridien if (guide_v) then ncidv=NCOPN('v.nc',NCNOWRIT,rcode) varidv=NCVID(ncidv,'VWND',rcode) print*,'ncidv,varidv',ncidv,varidv if (ncidpl.eq.-99) ncidpl=ncidv endif c Temperature if (guide_T) then ncidt=NCOPN('T.nc',NCNOWRIT,rcode) varidt=NCVID(ncidt,'AIR',rcode) print*,'ncidt,varidt',ncidt,varidt if (ncidpl.eq.-99) ncidpl=ncidt endif c Humidite if (guide_Q) then ncidQ=NCOPN('hur.nc',NCNOWRIT,rcode) varidQ=NCVID(ncidQ,'RH',rcode) print*,'ncidQ,varidQ',ncidQ,varidQ if (ncidpl.eq.-99) ncidpl=ncidQ endif c Pression de surface if (guide_P) then ncidps=NCOPN('ps.nc',NCNOWRIT,rcode) varidps=NCVID(ncidps,'SP',rcode) print*,'ncidps,varidps',ncidps,varidps endif c Coordonnee verticale if (ncep) then print*,'Vous etes entrain de lire des donnees NCEP' varidpl=NCVID(ncidpl,'LEVEL',rcode) else print*,'Vous etes entrain de lire des donnees ECMWF' varidpl=NCVID(ncidpl,'PRESSURE',rcode) endif print*,'ncidu,varidpl',ncidu,varidpl endif print*,'ok1' c Niveaux de pression print*,'WARNING!!! Il n y a pas de test de coherence' print*,'sur le nombre de niveaux verticaux dans le fichier nc' #ifdef NC_DOUBLE status=NF_GET_VARA_DOUBLE(ncidpl,varidpl,1,nlevnc,pl) #else status=NF_GET_VARA_REAL(ncidpl,varidpl,1,nlevnc,pl) #endif c passage en pascal pl(:)=100.*pl(:) if (first) then do l=1,nlevnc print*,'PL(',l,')=',pl(l) enddo endif c ----------------------------------------------------------------- c lecture des champs u, v, T, ps c ----------------------------------------------------------------- c dimensions pour les champs scalaires et le vent zonal c ----------------------------------------------------- start(1)=1 start(2)=1 start(3)=1 start(4)=timestep count(1)=iip1 count(2)=jjp1 count(3)=nlevnc count(4)=1 c mise a zero des tableaux c ------------------------ unc(:,:,:)=0. vnc(:,:,:)=0. tnc(:,:,:)=0. Qnc(:,:,:)=0. c Vent zonal c ---------- if (guide_u) then print*,'avant la lecture de UNCEP nd de niv:',nlevnc #ifdef NC_DOUBLE status=NF_GET_VARA_DOUBLE(ncidu,varidu,start,count,unc) #else status=NF_GET_VARA_REAL(ncidu,varidu,start,count,unc) #endif c call dump2d(iip1,jjp1,unc,'VENT NCEP ') c call dump2d(iip1,40,unc(1,1,nlevnc),'VENT NCEP ') print*,'WARNING!!! Correction bidon pour palier a un ' print*,'probleme dans la creation des fichiers nc' call correctbid(iim,jjp1*nlevnc,unc) call dump2d(iip1,jjp1,unc,'UNC COUCHE 1 ') endif c Temperature c ----------- print*,'ncidt=',ncidt,'varidt=',varidt,'start=',start print*,'count=',count if (guide_T) then #ifdef NC_DOUBLE status=NF_GET_VARA_DOUBLE(ncidt,varidt,start,count,tnc) #else status=NF_GET_VARA_REAL(ncidt,varidt,start,count,tnc) #endif call dump2d(iip1,jjp1,tnc,'TNC COUCHE 1 AAA ') call correctbid(iim,jjp1*nlevnc,tnc) call dump2d(iip1,jjp1,tnc,'TNC COUCHE 1 BBB ') endif c Humidite c -------- if (guide_Q) then #ifdef NC_DOUBLE status=NF_GET_VARA_DOUBLE(ncidQ,varidQ,start,count,Qnc) #else status=NF_GET_VARA_REAL(ncidQ,varidQ,start,count,Qnc) #endif call correctbid(iim,jjp1*nlevnc,Qnc) call dump2d(iip1,jjp1,Qnc,'QNC COUCHE 1 ') endif count(2)=jjm c Vent meridien c ------------- if (guide_v) then #ifdef NC_DOUBLE status=NF_GET_VARA_DOUBLE(ncidv,varidv,start,count,vnc) #else status=NF_GET_VARA_REAL(ncidv,varidv,start,count,vnc) #endif call correctbid(iim,jjm*nlevnc,vnc) call dump2d(iip1,jjm,vnc,'VNC COUCHE 1 ') endif start(3)=timestep start(4)=0 count(2)=jjp1 count(3)=1 count(4)=0 c Pression de surface c ------------------- if (guide_P) then #ifdef NC_DOUBLE status=NF_GET_VARA_DOUBLE(ncidps,varidps,start,count,psnc) #else status=NF_GET_VARA_REAL(ncidps,varidps,start,count,psnc) #endif call dump2d(iip1,jjp1,psnc,'PSNC COUCHE 1 ') call correctbid(iim,jjp1,psnc) endif c ----------------------------------------------------------------- c Interpollation verticale sur les niveaux modele c ----------------------------------------------------------------- call reanalyse2nat(nlevnc,psi,unc,vnc,tnc,Qnc,psnc,pl,u,v,t,Q s ,ps,masse,pk) call dump2d(iip1,jjm,v,'V COUCHE APRES ') c ----------------------------------------------------------------- c Passage aux variables du modele (vents covariants, temperature c potentielle et humidite specifique) c ----------------------------------------------------------------- call nat2gcm(u,v,t,Q,pk,u,v,t,Q) print*,'TIMESTEP ',timestep if(mode.ne.1) stop'mode pas egal 0' c call dump2d(iip1,jjm,v,'VCOV COUCHE 1 ') c Lignes introduites a une epoque pour un probleme oublie... c do l=1,llm c do i=1,iip1 c v(i,1,l)=0. c v(i,jjm,l)=0. c enddo c enddo first=.false. return end c=========================================================================== subroutine reanalyse2nat(nlevnc,psi s ,unc,vnc,tnc,qnc,psnc,pl,u,v,t,q s ,ps,masse,pk) c=========================================================================== c ----------------------------------------------------------------- c Inversion Nord/sud de la grille + interpollation sur les niveaux c verticaux du modele. c ----------------------------------------------------------------- implicit none #include "dimensions.h" #include "paramet.h" #include "comgeom2.h" #include "comvert.h" #include "comconst.h" #include "guide.h" integer nlevnc real psi(iip1,jjp1) real u(iip1,jjp1,llm),v(iip1,jjm,llm) real t(iip1,jjp1,llm),ps(iip1,jjp1),q(iip1,jjp1,llm) real pl(nlevnc) real unc(iip1,jjp1,nlevnc),vnc(iip1,jjm,nlevnc) real tnc(iip1,jjp1,nlevnc),psnc(iip1,jjp1) real qnc(iip1,jjp1,nlevnc) real zu(iip1,jjp1,llm),zv(iip1,jjm,llm) real zt(iip1,jjp1,llm),zq(iip1,jjp1,llm) real pext(iip1,jjp1,llm) real pbarx(iip1,jjp1,llm),pbary(iip1,jjm,llm) real plunc(iip1,jjp1,llm),plvnc(iip1,jjm,llm) real plsnc(iip1,jjp1,llm) REAL alpha(iip1,jjp1,llm),beta(iip1,jjp1,llm) real p(iip1,jjp1,llmp1),pk(iip1,jjp1,llm),pks(iip1,jjp1) real pkf(iip1,jjp1,llm) real masse(iip1,jjp1,llm),pls(iip1,jjp1,llm) real prefkap,unskap integer i,j,l c ----------------------------------------------------------------- c calcul de la pression au milieu des couches. c ----------------------------------------------------------------- CALL pression( ip1jmp1, ap, bp, psi, p ) call massdair(p,masse) CALL exner_hyb(ip1jmp1,psi,p,alpha,beta,pks,pk,pkf) c .... Calcul de pls , pression au milieu des couches ,en Pascals unskap=1./kappa prefkap = preff ** kappa c PRINT *,' Pref kappa unskap ',preff,kappa,unskap DO l = 1, llm DO j=1,jjp1 DO i =1, iip1 pls(i,j,l) = preff * ( pk(i,j,l)/cpp) ** unskap ENDDO ENDDO ENDDO c ----------------------------------------------------------------- c calcul des pressions pour les grilles u et v c ----------------------------------------------------------------- do l=1,llm do j=1,jjp1 do i=1,iip1 pext(i,j,l)=pls(i,j,l)*aire(i,j) enddo enddo enddo call massbar(pext, pbarx, pbary ) do l=1,llm do j=1,jjp1 do i=1,iip1 plunc(i,jjp1+1-j,l)=pbarx(i,j,l)/aireu(i,j) plsnc(i,jjp1+1-j,l)=pls(i,j,l) enddo enddo enddo do l=1,llm do j=1,jjm do i=1,iip1 plvnc(i,jjm+1-j,l)=pbary(i,j,l)/airev(i,j) enddo enddo enddo c ----------------------------------------------------------------- if (guide_P) then do j=1,jjp1 do i=1,iim ps(i,j)=psnc(i,jjp1+1-j) enddo ps(iip1,j)=ps(1,j) enddo endif c ----------------------------------------------------------------- call pres2lev(unc,zu,nlevnc,llm,pl,plunc,iip1,jjp1) call pres2lev(vnc,zv,nlevnc,llm,pl,plvnc,iip1,jjm ) call pres2lev(tnc,zt,nlevnc,llm,pl,plsnc,iip1,jjp1) call pres2lev(qnc,zq,nlevnc,llm,pl,plsnc,iip1,jjp1) c call dump2d(iip1,jjp1,ps,'PS ') c call dump2d(iip1,jjp1,psu,'PS ') c call dump2d(iip1,jjm,psv,'PS ') c Inversion Nord/Sud do l=1,llm do j=1,jjp1 do i=1,iim u(i,j,l)=zu(i,jjp1+1-j,l) t(i,j,l)=zt(i,jjp1+1-j,l) q(i,j,l)=zq(i,jjp1+1-j,l) enddo u(iip1,j,l)=u(1,j,l) t(iip1,j,l)=t(1,j,l) q(iip1,j,l)=q(1,j,l) enddo enddo do l=1,llm do j=1,jjm do i=1,iim v(i,j,l)=zv(i,jjm+1-j,l) enddo v(iip1,j,l)=v(1,j,l) enddo enddo return end c=========================================================================== subroutine nat2gcm(u,v,t,rh,pk,ucov,vcov,teta,q) c=========================================================================== implicit none #include "dimensions.h" #include "paramet.h" #include "comgeom2.h" #include "comconst.h" #include "comvert.h" #include "guide.h" real u(iip1,jjp1,llm),v(iip1,jjm,llm) real t(iip1,jjp1,llm),pk(iip1,jjp1,llm),rh(iip1,jjp1,llm) real ps(iip1,jjp1) real ucov(iip1,jjp1,llm),vcov(iip1,jjm,llm) real teta(iip1,jjp1,llm),q(iip1,jjp1,llm) real pres(iip1,jjp1,llm),qsat(iip1,jjp1,llm) real unskap integer i,j,l print*,'Entree dans nat2gcm' c ucov(:,:,:)=0. c do l=1,llm c ucov(:,2:jjm,l)=u(:,2:jjm,l)*cu(:,2:jjm) c enddo c ucov(iip1,:,:)=ucov(1,:,:) c teta(:,:,:)=t(:,:,:)*cpp/pk(:,:,:) c teta(iip1,:,:)=teta(1,:,:) c calcul de ucov et de la temperature potentielle do l=1,llm do j=1,jjp1 do i=1,iim ucov(i,j,l)=u(i,j,l)*cu(i,j) teta(i,j,l)=t(i,j,l)*cpp/pk(i,j,l) enddo ucov(iip1,j,l)=ucov(1,j,l) teta(iip1,j,l)=teta(1,j,l) enddo do i=1,iip1 ucov(i,1,l)=0. ucov(i,jjp1,l)=0. teta(i,1,l)=teta(1,1,l) teta(i,jjp1,l)=teta(1,jjp1,l) enddo enddo c calcul de ucov do l=1,llm do j=1,jjm do i=1,iim vcov(i,j,l)=v(i,j,l)*cv(i,j) enddo vcov(iip1,j,l)=vcov(1,j,l) enddo enddo c call dump2d(iip1,jjp1,teta,'TETA EN BAS ') c call dump2d(iip1,jjp1,teta(1,1,llm),'TETA EN HAUT ') c Humidite relative -> specifique c ------------------------------- if (1.eq.0) then c FINALEMENT ON GUIDE EN HUMIDITE RELATIVE print*,'calcul de unskap' unskap = 1./ kappa print*,'calcul de pres' pres(:,:,:)=preff*(pk(:,:,:)/cpp)**unskap print*,'calcul de qsat' call q_sat(iip1*jjp1*llm,t,pres,qsat) print*,'calcul de q' c ATTENTION : humidites relatives en % rh(:,:,:)=max(rh(:,:,:)*0.01,1.e-6) q(:,:,:)=qsat(:,:,:)*rh(:,:,:) print*,'calcul de q OK' call dump2d(iip1,jjp1,pres,'PRESSION PREMIERE COUCHE ') call dump2d(iip1,jjp1,q,'HUMIDITE SPECIFIQUE COUCHE 1 ') endif return end c=========================================================================== subroutine correctbid(iim,nl,x) c=========================================================================== integer iim,nl real x(iim+1,nl) integer i,l real zz do l=1,nl do i=2,iim-1 if(abs(x(i,l)).gt.1.e10) then zz=0.5*(x(i-1,l)+x(i+1,l)) c print*,'correction ',i,l,x(i,l),zz x(i,l)=zz endif enddo enddo return end