! $Id$ MODULE guide_mod !======================================================================= ! Auteur: F.Hourdin ! F. Codron 01/09 !======================================================================= USE getparam, ONLY: ini_getparam, fin_getparam, getpar USE Write_Field USE netcdf, ONLY: nf90_nowrite, nf90_open, nf90_inq_varid, nf90_close, & nf90_inq_dimid, nf90_inquire_dimension, nf90_float, nf90_def_var, & nf90_create, nf90_def_dim, nf90_open, nf90_unlimited, nf90_write, nf90_enddef, nf90_redef, & nf90_close, nf90_inq_varid, nf90_get_var, nf90_noerr, nf90_clobber, & nf90_64bit_offset, nf90_inq_dimid, nf90_inquire_dimension, nf90_put_var USE pres2lev_mod, ONLY: pres2lev IMPLICIT NONE ! --------------------------------------------- ! Declarations des cles logiques et parametres ! --------------------------------------------- INTEGER, PRIVATE, SAVE :: iguide_read,iguide_int,iguide_sav INTEGER, PRIVATE, SAVE :: nlevnc, guide_plevs LOGICAL, PRIVATE, SAVE :: guide_u,guide_v,guide_T,guide_Q,guide_P LOGICAL, PRIVATE, SAVE :: guide_hr,guide_teta LOGICAL, PRIVATE, SAVE :: guide_BL,guide_reg,guide_add,gamma4,guide_zon LOGICAL, PRIVATE, SAVE :: invert_p,invert_y,ini_anal LOGICAL, PRIVATE, SAVE :: guide_2D,guide_sav,guide_modele !FC LOGICAL, PRIVATE, SAVE :: convert_Pa REAL, PRIVATE, SAVE :: tau_min_u,tau_max_u REAL, PRIVATE, SAVE :: tau_min_v,tau_max_v REAL, PRIVATE, SAVE :: tau_min_T,tau_max_T REAL, PRIVATE, SAVE :: tau_min_Q,tau_max_Q REAL, PRIVATE, SAVE :: tau_min_P,tau_max_P REAL, PRIVATE, SAVE :: lat_min_g,lat_max_g REAL, PRIVATE, SAVE :: lon_min_g,lon_max_g REAL, PRIVATE, SAVE :: tau_lon,tau_lat REAL, PRIVATE, SAVE :: plim_guide_BL REAL, ALLOCATABLE, DIMENSION(:), PRIVATE, SAVE :: alpha_u,alpha_v REAL, ALLOCATABLE, DIMENSION(:, :), PRIVATE, SAVE :: alpha_T,alpha_Q REAL, ALLOCATABLE, DIMENSION(:), PRIVATE, SAVE :: alpha_P,alpha_pcor ! --------------------------------------------- ! Variables de guidage ! --------------------------------------------- ! Variables des fichiers de guidage REAL, ALLOCATABLE, DIMENSION(:,:,:), PRIVATE, SAVE :: unat1,unat2 REAL, ALLOCATABLE, DIMENSION(:,:,:), PRIVATE, SAVE :: vnat1,vnat2 REAL, ALLOCATABLE, DIMENSION(:,:,:), PRIVATE, SAVE :: tnat1,tnat2 REAL, ALLOCATABLE, DIMENSION(:,:,:), PRIVATE, SAVE :: qnat1,qnat2 REAL, ALLOCATABLE, DIMENSION(:,:,:), PRIVATE, SAVE :: pnat1,pnat2 REAL, ALLOCATABLE, DIMENSION(:,:), PRIVATE, SAVE :: psnat1,psnat2 REAL, ALLOCATABLE, DIMENSION(:), PRIVATE, SAVE :: apnc,bpnc ! Variables aux dimensions du modele REAL, ALLOCATABLE, DIMENSION(:,:), PRIVATE, SAVE :: ugui1,ugui2 REAL, ALLOCATABLE, DIMENSION(:,:), PRIVATE, SAVE :: vgui1,vgui2 REAL, ALLOCATABLE, DIMENSION(:,:), PRIVATE, SAVE :: tgui1,tgui2 REAL, ALLOCATABLE, DIMENSION(:,:), PRIVATE, SAVE :: qgui1,qgui2 REAL, ALLOCATABLE, DIMENSION(:), PRIVATE, SAVE :: psgui1,psgui2 CONTAINS !======================================================================= SUBROUTINE guide_init use netcdf, only: nf90_noerr USE control_mod, ONLY: day_step USE serre_mod, ONLY: grossismx IMPLICIT NONE INCLUDE "dimensions.h" INCLUDE "paramet.h" INTEGER :: error,ncidpl,rid,rcod CHARACTER (len = 80) :: abort_message CHARACTER (len = 20) :: modname = 'guide_init' CHARACTER (len = 20) :: namedim ! --------------------------------------------- ! Lecture des parametres: ! --------------------------------------------- CALL ini_getparam("nudging_parameters_out.txt") ! Variables guidees CALL getpar('guide_u',.TRUE.,guide_u,'guidage de u') CALL getpar('guide_v',.TRUE.,guide_v,'guidage de v') CALL getpar('guide_T',.TRUE.,guide_T,'guidage de T') CALL getpar('guide_P',.TRUE.,guide_P,'guidage de P') CALL getpar('guide_Q',.TRUE.,guide_Q,'guidage de Q') CALL getpar('guide_hr',.TRUE.,guide_hr,'guidage de Q par H.R') CALL getpar('guide_teta',.FALSE.,guide_teta,'guidage de T par Teta') CALL getpar('guide_add',.FALSE.,guide_add,'forçage constant?') CALL getpar('guide_zon',.FALSE.,guide_zon,'guidage moy zonale') if (guide_zon .and. abs(grossismx - 1.) > 0.01) & CALL abort_gcm("guide_init", & "zonal nudging requires grid regular in longitude", 1) ! Constantes de rappel. Unite : fraction de jour CALL getpar('tau_min_u',0.02,tau_min_u,'Cste de rappel min, u') CALL getpar('tau_max_u', 10.,tau_max_u,'Cste de rappel max, u') CALL getpar('tau_min_v',0.02,tau_min_v,'Cste de rappel min, v') CALL getpar('tau_max_v', 10.,tau_max_v,'Cste de rappel max, v') CALL getpar('tau_min_T',0.02,tau_min_T,'Cste de rappel min, T') CALL getpar('tau_max_T', 10.,tau_max_T,'Cste de rappel max, T') CALL getpar('tau_min_Q',0.02,tau_min_Q,'Cste de rappel min, Q') CALL getpar('tau_max_Q', 10.,tau_max_Q,'Cste de rappel max, Q') CALL getpar('tau_min_P',0.02,tau_min_P,'Cste de rappel min, P') CALL getpar('tau_max_P', 10.,tau_max_P,'Cste de rappel max, P') CALL getpar('gamma4',.FALSE.,gamma4,'Zone sans rappel elargie') CALL getpar('guide_BL',.TRUE.,guide_BL,'guidage dans C.Lim') CALL getpar('plim_guide_BL',85000.,plim_guide_BL,'BL top presnivs value') ! Sauvegarde du forçage CALL getpar('guide_sav',.FALSE.,guide_sav,'sauvegarde guidage') CALL getpar('iguide_sav',4,iguide_sav,'freq. sauvegarde guidage') ! frequences f>0: fx/jour; f<0: tous les f jours; f=0: 1 seule fois. IF (iguide_sav>0) THEN iguide_sav=day_step/iguide_sav ELSE if (iguide_sav == 0) then iguide_sav = huge(0) ELSE iguide_sav=day_step*iguide_sav ENDIF ! Guidage regional seulement (sinon constant ou suivant le zoom) CALL getpar('guide_reg',.FALSE.,guide_reg,'guidage regional') CALL getpar('lat_min_g',-90.,lat_min_g,'Latitude mini guidage ') CALL getpar('lat_max_g', 90.,lat_max_g,'Latitude maxi guidage ') CALL getpar('lon_min_g',-180.,lon_min_g,'longitude mini guidage ') CALL getpar('lon_max_g', 180.,lon_max_g,'longitude maxi guidage ') CALL getpar('tau_lat', 5.,tau_lat,'raideur lat guide regional ') CALL getpar('tau_lon', 5.,tau_lon,'raideur lon guide regional ') ! Parametres pour lecture des fichiers CALL getpar('iguide_read',4,iguide_read,'freq. lecture guidage') CALL getpar('iguide_int',4,iguide_int,'freq. interpolation vert') IF (iguide_int==0) THEN iguide_int=1 ELSEIF (iguide_int>0) THEN iguide_int=day_step/iguide_int ELSE iguide_int=day_step*iguide_int ENDIF CALL getpar('guide_plevs',0,guide_plevs,'niveaux pression fichiers guidage') ! Pour compatibilite avec ancienne version avec guide_modele CALL getpar('guide_modele',.FALSE.,guide_modele,'niveaux pression ap+bp*psol') IF (guide_modele) THEN guide_plevs=1 ENDIF !FC CALL getpar('convert_Pa',.TRUE.,convert_Pa,'Convert Pressure levels in Pa') ! Fin raccord CALL getpar('ini_anal',.FALSE.,ini_anal,'Etat initial = analyse') CALL getpar('guide_invertp',.TRUE.,invert_p,'niveaux p inverses') CALL getpar('guide_inverty',.TRUE.,invert_y,'inversion N-S') CALL getpar('guide_2D',.FALSE.,guide_2D,'fichier guidage lat-P') CALL fin_getparam ! --------------------------------------------- ! Determination du nombre de niveaux verticaux ! des fichiers guidage ! --------------------------------------------- ncidpl=-99 if (guide_plevs==1) then if (ncidpl==-99) then rcod=nf90_open('apbp.nc',nf90_nowrite, ncidpl) if (rcod/=nf90_noerr) THEN abort_message=' Nudging error -> no file apbp.nc' CALL abort_gcm(modname,abort_message,1) endif endif elseif (guide_plevs==2) then if (ncidpl==-99) then rcod=nf90_open('P.nc',nf90_nowrite,ncidpl) if (rcod/=nf90_noerr) THEN abort_message=' Nudging error -> no file P.nc' CALL abort_gcm(modname,abort_message,1) endif endif elseif (guide_u) then if (ncidpl==-99) then rcod=nf90_open('u.nc',nf90_nowrite,ncidpl) if (rcod/=nf90_noerr) THEN CALL abort_gcm(modname, & ' Nudging error -> no file u.nc',1) endif endif elseif (guide_v) then if (ncidpl==-99) then rcod=nf90_open('v.nc',nf90_nowrite,ncidpl) if (rcod/=nf90_noerr) THEN CALL abort_gcm(modname, & ' Nudging error -> no file v.nc',1) endif endif elseif (guide_T) then if (ncidpl==-99) then rcod=nf90_open('T.nc',nf90_nowrite,ncidpl) if (rcod/=nf90_noerr) THEN CALL abort_gcm(modname, & ' Nudging error -> no file T.nc',1) endif endif elseif (guide_Q) then if (ncidpl==-99) then rcod=nf90_open('hur.nc',nf90_nowrite, ncidpl) if (rcod/=nf90_noerr) THEN CALL abort_gcm(modname, & ' Nudging error -> no file hur.nc',1) endif endif endif error=nf90_inq_dimid(ncidpl,'LEVEL',rid) IF (error/=nf90_noerr) error=nf90_inq_dimid(ncidpl,'PRESSURE',rid) IF (error/=nf90_noerr) THEN CALL abort_gcm(modname,'Nudging: error reading pressure levels',1) ENDIF error=nf90_inquire_dimension(ncidpl,rid,len=nlevnc) write(*,*)trim(modname)//' : number of vertical levels nlevnc', nlevnc rcod = nf90_close(ncidpl) ! --------------------------------------------- ! Allocation des variables ! --------------------------------------------- abort_message='nudging allocation error' ALLOCATE(apnc(nlevnc), stat = error) IF (error /= 0) CALL abort_gcm(modname,abort_message,1) ALLOCATE(bpnc(nlevnc), stat = error) IF (error /= 0) CALL abort_gcm(modname,abort_message,1) apnc=0.;bpnc=0. ALLOCATE(alpha_pcor(llm), stat = error) IF (error /= 0) CALL abort_gcm(modname,abort_message,1) ALLOCATE(alpha_u(ip1jmp1), stat = error) IF (error /= 0) CALL abort_gcm(modname,abort_message,1) ALLOCATE(alpha_v(ip1jm), stat = error) IF (error /= 0) CALL abort_gcm(modname,abort_message,1) ALLOCATE(alpha_T(iip1, jjp1), stat = error) IF (error /= 0) CALL abort_gcm(modname,abort_message,1) ALLOCATE(alpha_Q(iip1, jjp1), stat = error) IF (error /= 0) CALL abort_gcm(modname,abort_message,1) ALLOCATE(alpha_P(ip1jmp1), stat = error) IF (error /= 0) CALL abort_gcm(modname,abort_message,1) alpha_u=0.;alpha_v=0;alpha_T=0;alpha_Q=0;alpha_P=0 IF (guide_u) THEN ALLOCATE(unat1(iip1,jjp1,nlevnc), stat = error) IF (error /= 0) CALL abort_gcm(modname,abort_message,1) ALLOCATE(ugui1(ip1jmp1,llm), stat = error) IF (error /= 0) CALL abort_gcm(modname,abort_message,1) ALLOCATE(unat2(iip1,jjp1,nlevnc), stat = error) IF (error /= 0) CALL abort_gcm(modname,abort_message,1) ALLOCATE(ugui2(ip1jmp1,llm), stat = error) IF (error /= 0) CALL abort_gcm(modname,abort_message,1) unat1=0.;unat2=0.;ugui1=0.;ugui2=0. ENDIF IF (guide_T) THEN ALLOCATE(tnat1(iip1,jjp1,nlevnc), stat = error) IF (error /= 0) CALL abort_gcm(modname,abort_message,1) ALLOCATE(tgui1(ip1jmp1,llm), stat = error) IF (error /= 0) CALL abort_gcm(modname,abort_message,1) ALLOCATE(tnat2(iip1,jjp1,nlevnc), stat = error) IF (error /= 0) CALL abort_gcm(modname,abort_message,1) ALLOCATE(tgui2(ip1jmp1,llm), stat = error) IF (error /= 0) CALL abort_gcm(modname,abort_message,1) tnat1=0.;tnat2=0.;tgui1=0.;tgui2=0. ENDIF IF (guide_Q) THEN ALLOCATE(qnat1(iip1,jjp1,nlevnc), stat = error) IF (error /= 0) CALL abort_gcm(modname,abort_message,1) ALLOCATE(qgui1(ip1jmp1,llm), stat = error) IF (error /= 0) CALL abort_gcm(modname,abort_message,1) ALLOCATE(qnat2(iip1,jjp1,nlevnc), stat = error) IF (error /= 0) CALL abort_gcm(modname,abort_message,1) ALLOCATE(qgui2(ip1jmp1,llm), stat = error) IF (error /= 0) CALL abort_gcm(modname,abort_message,1) qnat1=0.;qnat2=0.;qgui1=0.;qgui2=0. ENDIF IF (guide_v) THEN ALLOCATE(vnat1(iip1,jjm,nlevnc), stat = error) IF (error /= 0) CALL abort_gcm(modname,abort_message,1) ALLOCATE(vgui1(ip1jm,llm), stat = error) IF (error /= 0) CALL abort_gcm(modname,abort_message,1) ALLOCATE(vnat2(iip1,jjm,nlevnc), stat = error) IF (error /= 0) CALL abort_gcm(modname,abort_message,1) ALLOCATE(vgui2(ip1jm,llm), stat = error) IF (error /= 0) CALL abort_gcm(modname,abort_message,1) vnat1=0.;vnat2=0.;vgui1=0.;vgui2=0. ENDIF IF (guide_plevs==2) THEN ALLOCATE(pnat1(iip1,jjp1,nlevnc), stat = error) IF (error /= 0) CALL abort_gcm(modname,abort_message,1) ALLOCATE(pnat2(iip1,jjp1,nlevnc), stat = error) IF (error /= 0) CALL abort_gcm(modname,abort_message,1) pnat1=0.;pnat2=0.; ENDIF IF (guide_P.OR.guide_plevs==1) THEN ALLOCATE(psnat1(iip1,jjp1), stat = error) IF (error /= 0) CALL abort_gcm(modname,abort_message,1) ALLOCATE(psnat2(iip1,jjp1), stat = error) IF (error /= 0) CALL abort_gcm(modname,abort_message,1) psnat1=0.;psnat2=0.; ENDIF IF (guide_P) THEN ALLOCATE(psgui2(ip1jmp1), stat = error) IF (error /= 0) CALL abort_gcm(modname,abort_message,1) ALLOCATE(psgui1(ip1jmp1), stat = error) IF (error /= 0) CALL abort_gcm(modname,abort_message,1) psgui1=0.;psgui2=0. ENDIF ! --------------------------------------------- ! Lecture du premier etat de guidage. ! --------------------------------------------- IF (guide_2D) THEN CALL guide_read2D(1) ELSE CALL guide_read(1) ENDIF IF (guide_v) vnat1=vnat2 IF (guide_u) unat1=unat2 IF (guide_T) tnat1=tnat2 IF (guide_Q) qnat1=qnat2 IF (guide_plevs==2) pnat1=pnat2 IF (guide_P.OR.guide_plevs==1) psnat1=psnat2 END SUBROUTINE guide_init !======================================================================= SUBROUTINE guide_main(itau,ucov,vcov,teta,q,masse,ps) USE exner_hyb_m, ONLY: exner_hyb USE exner_milieu_m, ONLY: exner_milieu USE control_mod, ONLY: day_step, iperiod USE comconst_mod, ONLY: cpp, dtvr, daysec,kappa USE comvert_mod, ONLY: ap, bp, preff, presnivs, pressure_exner IMPLICIT NONE INCLUDE "dimensions.h" INCLUDE "paramet.h" INCLUDE "iniprint.h" ! Variables entree INTEGER, INTENT(IN) :: itau !pas de temps REAL, DIMENSION (ip1jmp1,llm), INTENT(INOUT) :: ucov,teta,q,masse REAL, DIMENSION (ip1jm,llm), INTENT(INOUT) :: vcov REAL, DIMENSION (ip1jmp1), INTENT(INOUT) :: ps ! Variables locales LOGICAL, SAVE :: first=.TRUE. LOGICAL :: f_out ! sortie guidage REAL, DIMENSION (ip1jmp1,llm) :: f_add ! var aux: champ de guidage REAL :: pk(ip1jmp1,llm) ! Exner at mid-layers REAL :: pks(ip1jmp1) ! Exner at the surface REAL :: unskap ! 1./kappa REAL, DIMENSION (ip1jmp1,llmp1) :: p ! Pressure at inter-layers ! Compteurs temps: INTEGER, SAVE :: step_rea,count_no_rea,itau_test ! lecture guidage REAL :: ditau, dday_step REAL :: tau,reste ! position entre 2 etats de guidage REAL, SAVE :: factt ! pas de temps en fraction de jour INTEGER :: l CHARACTER(LEN=20) :: modname="guide_main" CHARACTER (len = 80) :: abort_message !----------------------------------------------------------------------- ! Initialisations au premier passage !----------------------------------------------------------------------- IF (first) THEN first=.FALSE. CALL guide_init itau_test=1001 step_rea=1 count_no_rea=0 ! Calcul des constantes de rappel factt=dtvr*iperiod/daysec CALL tau2alpha(3,iip1,jjm ,factt,tau_min_v,tau_max_v,alpha_v) CALL tau2alpha(2,iip1,jjp1,factt,tau_min_u,tau_max_u,alpha_u) CALL tau2alpha(1,iip1,jjp1,factt,tau_min_T,tau_max_T,alpha_T) CALL tau2alpha(1,iip1,jjp1,factt,tau_min_P,tau_max_P,alpha_P) CALL tau2alpha(1,iip1,jjp1,factt,tau_min_Q,tau_max_Q,alpha_Q) ! correction de rappel dans couche limite if (guide_BL) then alpha_pcor(:)=1. else do l=1,llm alpha_pcor(l)=(1.+tanh(((plim_guide_BL-presnivs(l))/preff)/0.05))/2. enddo endif ! ini_anal: etat initial egal au guidage IF (ini_anal) THEN CALL guide_interp(ps,teta) IF (guide_u) ucov=ugui2 IF (guide_v) vcov=ugui2 IF (guide_T) teta=tgui2 IF (guide_Q) q=qgui2 IF (guide_P) THEN ps=psgui2 CALL pression(ip1jmp1,ap,bp,ps,p) CALL massdair(p,masse) ENDIF RETURN ENDIF ! Verification structure guidage ! IF (guide_u) THEN ! CALL writefield('unat',unat1) ! CALL writefield('ucov',RESHAPE(ucov,(/iip1,jjp1,llm/))) ! ENDIF ! IF (guide_T) THEN ! CALL writefield('tnat',tnat1) ! CALL writefield('teta',RESHAPE(teta,(/iip1,jjp1,llm/))) ! ENDIF ENDIF !first !----------------------------------------------------------------------- ! Lecture des fichiers de guidage ? !----------------------------------------------------------------------- IF (iguide_read/=0) THEN ditau=real(itau) dday_step=real(day_step) IF (iguide_read<0) THEN tau=ditau/dday_step/REAL(iguide_read) ELSE tau=REAL(iguide_read)*ditau/dday_step ENDIF reste=tau-AINT(tau) IF (reste==0.) THEN IF (itau_test==itau) THEN write(lunout,*)trim(modname)//' second pass in advreel at itau=',& itau abort_message='stopped' CALL abort_gcm(modname,abort_message,1) ELSE IF (guide_v) vnat1=vnat2 IF (guide_u) unat1=unat2 IF (guide_T) tnat1=tnat2 IF (guide_Q) qnat1=qnat2 IF (guide_plevs==2) pnat1=pnat2 IF (guide_P.OR.guide_plevs==1) psnat1=psnat2 step_rea=step_rea+1 itau_test=itau write(*,*)trim(modname)//' Reading nudging files, step ',& step_rea,'after ',count_no_rea,' skips' IF (guide_2D) THEN CALL guide_read2D(step_rea) ELSE CALL guide_read(step_rea) ENDIF count_no_rea=0 ENDIF ELSE count_no_rea=count_no_rea+1 ENDIF ENDIF !iguide_read=0 !----------------------------------------------------------------------- ! Interpolation et conversion des champs de guidage !----------------------------------------------------------------------- IF (MOD(itau,iguide_int)==0) THEN CALL guide_interp(ps,teta) ENDIF ! Repartition entre 2 etats de guidage IF (iguide_read/=0) THEN tau=reste ELSE tau=1. ENDIF !----------------------------------------------------------------------- ! Ajout des champs de guidage !----------------------------------------------------------------------- ! Sauvegarde du guidage? f_out=((MOD(itau,iguide_sav)==0).AND.guide_sav) IF (f_out) THEN ! compute pressures at layer interfaces CALL pression(ip1jmp1,ap,bp,ps,p) if (pressure_exner) then CALL exner_hyb(ip1jmp1,ps,p,pks,pk) else CALL exner_milieu(ip1jmp1,ps,p,pks,pk) endif unskap=1./kappa ! Now compute pressures at mid-layer do l=1,llm p(:,l)=preff*(pk(:,l)/cpp)**unskap enddo CALL guide_out("SP",jjp1,llm,p(:,1:llm)) ENDIF if (guide_u) then if (guide_add) then f_add=(1.-tau)*ugui1+tau*ugui2 else f_add=(1.-tau)*ugui1+tau*ugui2-ucov endif if (guide_zon) CALL guide_zonave(1,jjp1,llm,f_add) CALL guide_addfield(ip1jmp1,llm,f_add,alpha_u) IF (f_out) CALL guide_out("ua",jjp1,llm,(1.-tau)*ugui1+tau*ugui2) IF (f_out) CALL guide_out("u",jjp1,llm,ucov) IF (f_out) CALL guide_out("ucov",jjp1,llm,f_add/factt) ucov=ucov+f_add endif if (guide_T) then if (guide_add) then f_add=(1.-tau)*tgui1+tau*tgui2 else f_add=(1.-tau)*tgui1+tau*tgui2-teta endif if (guide_zon) CALL guide_zonave(2,jjp1,llm,f_add) CALL guide_addfield(ip1jmp1,llm,f_add,alpha_T) IF (f_out) CALL guide_out("teta",jjp1,llm,f_add/factt) teta=teta+f_add endif if (guide_P) then if (guide_add) then f_add(1:ip1jmp1,1)=(1.-tau)*psgui1+tau*psgui2 else f_add(1:ip1jmp1,1)=(1.-tau)*psgui1+tau*psgui2-ps endif if (guide_zon) CALL guide_zonave(2,jjp1,1,f_add(1:ip1jmp1,1)) CALL guide_addfield(ip1jmp1,1,f_add(1:ip1jmp1,1),alpha_P) ! IF (f_out) CALL guide_out("ps",jjp1,1,f_add(1:ip1jmp1,1)/factt) ps=ps+f_add(1:ip1jmp1,1) CALL pression(ip1jmp1,ap,bp,ps,p) CALL massdair(p,masse) endif if (guide_Q) then if (guide_add) then f_add=(1.-tau)*qgui1+tau*qgui2 else f_add=(1.-tau)*qgui1+tau*qgui2-q endif if (guide_zon) CALL guide_zonave(2,jjp1,llm,f_add) CALL guide_addfield(ip1jmp1,llm,f_add,alpha_Q) IF (f_out) CALL guide_out("q",jjp1,llm,f_add/factt) q=q+f_add endif if (guide_v) then if (guide_add) then f_add(1:ip1jm,:)=(1.-tau)*vgui1+tau*vgui2 else f_add(1:ip1jm,:)=(1.-tau)*vgui1+tau*vgui2-vcov endif if (guide_zon) CALL guide_zonave(2,jjm,llm,f_add(1:ip1jm,:)) CALL guide_addfield(ip1jm,llm,f_add(1:ip1jm,:),alpha_v) IF (f_out) CALL guide_out("v",jjm,llm,vcov) IF (f_out) CALL guide_out("va",jjm,llm,(1.-tau)*vgui1+tau*vgui2) IF (f_out) CALL guide_out("vcov",jjm,llm,f_add(1:ip1jm,:)/factt) vcov=vcov+f_add(1:ip1jm,:) endif END SUBROUTINE guide_main !======================================================================= SUBROUTINE guide_addfield(hsize,vsize,field,alpha) ! field1=a*field1+alpha*field2 IMPLICIT NONE ! input variables INTEGER, INTENT(IN) :: hsize INTEGER, INTENT(IN) :: vsize REAL, DIMENSION(hsize), INTENT(IN) :: alpha REAL, DIMENSION(hsize,vsize), INTENT(INOUT) :: field ! Local variables INTEGER :: l do l=1,vsize field(:,l)=alpha*field(:,l)*alpha_pcor(l) enddo END SUBROUTINE guide_addfield !======================================================================= SUBROUTINE guide_zonave(typ,hsize,vsize,field) USE comconst_mod, ONLY: pi IMPLICIT NONE INCLUDE "dimensions.h" INCLUDE "paramet.h" INCLUDE "comgeom.h" ! input/output variables INTEGER, INTENT(IN) :: typ INTEGER, INTENT(IN) :: vsize INTEGER, INTENT(IN) :: hsize REAL, DIMENSION(hsize*iip1,vsize), INTENT(INOUT) :: field ! Local variables LOGICAL, SAVE :: first=.TRUE. INTEGER, DIMENSION (2), SAVE :: imin, imax ! averaging domain INTEGER :: i,j,l,ij REAL, DIMENSION (iip1) :: lond ! longitude in Deg. REAL, DIMENSION (hsize,vsize):: fieldm ! zon-averaged field IF (first) THEN first=.FALSE. !Compute domain for averaging lond=rlonu*180./pi imin(1)=1;imax(1)=iip1; imin(2)=1;imax(2)=iip1; IF (guide_reg) THEN DO i=1,iim IF (lond(i)1.e10) then zz=0.5*(x(i-1,l)+x(i+1,l)) PRINT*,'correction ',i,l,x(i,l),zz x(i,l)=zz endif enddo enddo return END SUBROUTINE correctbid !=========================================================================== END MODULE guide_mod