source: LMDZ5/trunk/libf/dyn3dpar/guide_p_mod.F90 @ 1625

Last change on this file since 1625 was 1625, checked in by lguez, 12 years ago

Created logical variable "pressure_exner". "pressure_exner" replaces
"disvert_type" to choose between calls to "exner_hyb" and
"exner_milieu". If "pressure_exner" is true, pressure inside layers is
computed from Exner function ("exner_hyb"), else it is the mean of
pressure values at interfaces ("exner_milieu"). "disvert_type" now
only chooses between "disvert" and "disvert_noterre". Default value
for "pressure_exner" is true if "disvert_type" equals 1.

  • Property svn:executable set to *
File size: 64.1 KB
Line 
1!
2! $Id$
3!
4MODULE guide_p_mod
5
6!=======================================================================
7!   Auteur:  F.Hourdin
8!            F. Codron 01/09
9!=======================================================================
10
11  USE getparam
12  USE Write_Field_p
13  use netcdf, only: nf90_nowrite, nf90_open, nf90_inq_varid, nf90_close
14
15  IMPLICIT NONE
16
17! ---------------------------------------------
18! Declarations des cles logiques et parametres
19! ---------------------------------------------
20  INTEGER, PRIVATE, SAVE  :: iguide_read,iguide_int,iguide_sav
21  INTEGER, PRIVATE, SAVE  :: nlevnc, guide_plevs
22  LOGICAL, PRIVATE, SAVE  :: guide_u,guide_v,guide_T,guide_Q,guide_P
23  LOGICAL, PRIVATE, SAVE  :: guide_hr,guide_teta 
24  LOGICAL, PRIVATE, SAVE  :: guide_BL,guide_reg,guide_add,gamma4,guide_zon
25  LOGICAL, PRIVATE, SAVE  :: invert_p,invert_y,ini_anal
26  LOGICAL, PRIVATE, SAVE  :: guide_2D,guide_sav,guide_modele
27 
28  REAL, PRIVATE, SAVE     :: tau_min_u,tau_max_u
29  REAL, PRIVATE, SAVE     :: tau_min_v,tau_max_v
30  REAL, PRIVATE, SAVE     :: tau_min_T,tau_max_T
31  REAL, PRIVATE, SAVE     :: tau_min_Q,tau_max_Q
32  REAL, PRIVATE, SAVE     :: tau_min_P,tau_max_P
33
34  REAL, PRIVATE, SAVE     :: lat_min_g,lat_max_g
35  REAL, PRIVATE, SAVE     :: lon_min_g,lon_max_g
36  REAL, PRIVATE, SAVE     :: tau_lon,tau_lat
37
38  REAL, ALLOCATABLE, DIMENSION(:), PRIVATE, SAVE     :: alpha_u,alpha_v
39  REAL, ALLOCATABLE, DIMENSION(:), PRIVATE, SAVE     :: alpha_T,alpha_Q
40  REAL, ALLOCATABLE, DIMENSION(:), PRIVATE, SAVE     :: alpha_P,alpha_pcor
41 
42! ---------------------------------------------
43! Variables de guidage
44! ---------------------------------------------
45! Variables des fichiers de guidage
46  REAL, ALLOCATABLE, DIMENSION(:,:,:), PRIVATE, SAVE   :: unat1,unat2
47  REAL, ALLOCATABLE, DIMENSION(:,:,:), PRIVATE, SAVE   :: vnat1,vnat2
48  REAL, ALLOCATABLE, DIMENSION(:,:,:), PRIVATE, SAVE   :: tnat1,tnat2
49  REAL, ALLOCATABLE, DIMENSION(:,:,:), PRIVATE, SAVE   :: qnat1,qnat2
50  REAL, ALLOCATABLE, DIMENSION(:,:,:), PRIVATE, SAVE   :: pnat1,pnat2
51  REAL, ALLOCATABLE, DIMENSION(:,:),   PRIVATE, SAVE   :: psnat1,psnat2
52  REAL, ALLOCATABLE, DIMENSION(:),     PRIVATE, SAVE   :: apnc,bpnc
53! Variables aux dimensions du modele
54  REAL, ALLOCATABLE, DIMENSION(:,:),   PRIVATE, SAVE   :: ugui1,ugui2
55  REAL, ALLOCATABLE, DIMENSION(:,:),   PRIVATE, SAVE   :: vgui1,vgui2
56  REAL, ALLOCATABLE, DIMENSION(:,:),   PRIVATE, SAVE   :: tgui1,tgui2
57  REAL, ALLOCATABLE, DIMENSION(:,:),   PRIVATE, SAVE   :: qgui1,qgui2
58  REAL, ALLOCATABLE, DIMENSION(:),   PRIVATE, SAVE   :: psgui1,psgui2
59 
60  INTEGER,SAVE,PRIVATE :: ijb_u,ijb_v,ije_u,ije_v,ijn_u,ijn_v
61  INTEGER,SAVE,PRIVATE :: jjb_u,jjb_v,jje_u,jje_v,jjn_u,jjn_v
62
63
64CONTAINS
65!=======================================================================
66
67  SUBROUTINE guide_init
68   
69    USE control_mod
70    IMPLICIT NONE
71 
72    INCLUDE "dimensions.h"
73    INCLUDE "paramet.h"
74    INCLUDE "netcdf.inc"
75
76    INTEGER                :: error,ncidpl,rid,rcod
77    CHARACTER (len = 80)   :: abort_message
78    CHARACTER (len = 20)   :: modname = 'guide_init'
79
80! ---------------------------------------------
81! Lecture des parametres: 
82! ---------------------------------------------
83! Variables guidees
84    CALL getpar('guide_u',.true.,guide_u,'guidage de u')
85    CALL getpar('guide_v',.true.,guide_v,'guidage de v')
86    CALL getpar('guide_T',.true.,guide_T,'guidage de T')
87    CALL getpar('guide_P',.true.,guide_P,'guidage de P')
88    CALL getpar('guide_Q',.true.,guide_Q,'guidage de Q')
89    CALL getpar('guide_hr',.true.,guide_hr,'guidage de Q par H.R')
90    CALL getpar('guide_teta',.false.,guide_teta,'guidage de T par Teta')
91
92    CALL getpar('guide_add',.false.,guide_add,'for�age constant?')
93    CALL getpar('guide_zon',.false.,guide_zon,'guidage moy zonale')
94
95!   Constantes de rappel. Unite : fraction de jour
96    CALL getpar('tau_min_u',0.02,tau_min_u,'Cste de rappel min, u')
97    CALL getpar('tau_max_u', 10.,tau_max_u,'Cste de rappel max, u')
98    CALL getpar('tau_min_v',0.02,tau_min_v,'Cste de rappel min, v')
99    CALL getpar('tau_max_v', 10.,tau_max_v,'Cste de rappel max, v')
100    CALL getpar('tau_min_T',0.02,tau_min_T,'Cste de rappel min, T')
101    CALL getpar('tau_max_T', 10.,tau_max_T,'Cste de rappel max, T')
102    CALL getpar('tau_min_Q',0.02,tau_min_Q,'Cste de rappel min, Q')
103    CALL getpar('tau_max_Q', 10.,tau_max_Q,'Cste de rappel max, Q')
104    CALL getpar('tau_min_P',0.02,tau_min_P,'Cste de rappel min, P')
105    CALL getpar('tau_max_P', 10.,tau_max_P,'Cste de rappel max, P')
106    CALL getpar('gamma4',.false.,gamma4,'Zone sans rappel elargie')
107    CALL getpar('guide_BL',.true.,guide_BL,'guidage dans C.Lim')
108   
109! Sauvegarde du for�age
110    CALL getpar('guide_sav',.false.,guide_sav,'sauvegarde guidage')
111    CALL getpar('iguide_sav',4,iguide_sav,'freq. sauvegarde guidage')
112    ! frequences f>0: fx/jour; f<0: tous les f jours; f=0: 1 seule fois.
113    IF (iguide_sav.GT.0) THEN
114        iguide_sav=day_step/iguide_sav
115    ELSE
116        iguide_sav=day_step*iguide_sav
117    ENDIF
118
119! Guidage regional seulement (sinon constant ou suivant le zoom)
120    CALL getpar('guide_reg',.false.,guide_reg,'guidage regional')
121    CALL getpar('lat_min_g',-90.,lat_min_g,'Latitude mini guidage ')
122    CALL getpar('lat_max_g', 90.,lat_max_g,'Latitude maxi guidage ')
123    CALL getpar('lon_min_g',-180.,lon_min_g,'longitude mini guidage ')
124    CALL getpar('lon_max_g', 180.,lon_max_g,'longitude maxi guidage ')
125    CALL getpar('tau_lat', 5.,tau_lat,'raideur lat guide regional ')
126    CALL getpar('tau_lon', 5.,tau_lon,'raideur lon guide regional ')
127
128! Parametres pour lecture des fichiers
129    CALL getpar('iguide_read',4,iguide_read,'freq. lecture guidage')
130    CALL getpar('iguide_int',4,iguide_int,'freq. interpolation vert')
131    IF (iguide_int.EQ.0) THEN
132        iguide_int=1
133    ELSEIF (iguide_int.GT.0) THEN
134        iguide_int=day_step/iguide_int
135    ELSE
136        iguide_int=day_step*iguide_int
137    ENDIF
138    CALL getpar('guide_plevs',0,guide_plevs,'niveaux pression fichiers guidage')
139    ! Pour compatibilite avec ancienne version avec guide_modele
140    CALL getpar('guide_modele',.false.,guide_modele,'niveaux pression ap+bp*psol')
141    IF (guide_modele) THEN
142        guide_plevs=1
143    ENDIF
144    ! Fin raccord
145    CALL getpar('ini_anal',.false.,ini_anal,'Etat initial = analyse')
146    CALL getpar('guide_invertp',.true.,invert_p,'niveaux p inverses')
147    CALL getpar('guide_inverty',.true.,invert_y,'inversion N-S')
148    CALL getpar('guide_2D',.false.,guide_2D,'fichier guidage lat-P')
149
150! ---------------------------------------------
151! Determination du nombre de niveaux verticaux
152! des fichiers guidage
153! ---------------------------------------------
154    ncidpl=-99
155    if (guide_plevs.EQ.1) then
156       if (ncidpl.eq.-99) rcod=nf90_open('apbp.nc',Nf90_NOWRITe, ncidpl)
157    elseif (guide_plevs.EQ.2) then
158       if (ncidpl.EQ.-99) rcod=nf90_open('P.nc',Nf90_NOWRITe,ncidpl)
159    elseif (guide_u) then
160       if (ncidpl.eq.-99) rcod=nf90_open('u.nc',Nf90_NOWRITe,ncidpl)
161    elseif (guide_v) then
162       if (ncidpl.eq.-99) rcod=nf90_open('v.nc',nf90_nowrite,ncidpl)
163    elseif (guide_T) then
164       if (ncidpl.eq.-99) rcod=nf90_open('T.nc',nf90_nowrite,ncidpl)
165    elseif (guide_Q) then
166       if (ncidpl.eq.-99) rcod=nf90_open('hur.nc',nf90_nowrite, ncidpl)
167    endif
168    error=NF_INQ_DIMID(ncidpl,'LEVEL',rid)
169    IF (error.NE.NF_NOERR) error=NF_INQ_DIMID(ncidpl,'PRESSURE',rid)
170    IF (error.NE.NF_NOERR) THEN
171        print *,'Guide: probleme lecture niveaux pression'
172        CALL abort_gcm(modname,abort_message,1)
173    ENDIF
174    error=NF_INQ_DIMLEN(ncidpl,rid,nlevnc)
175    print *,'Guide: nombre niveaux vert. nlevnc', nlevnc
176    rcod = nf90_close(ncidpl)
177
178! ---------------------------------------------
179! Allocation des variables
180! ---------------------------------------------
181    abort_message='pb in allocation guide'
182
183    ALLOCATE(apnc(nlevnc), stat = error)
184    IF (error /= 0) CALL abort_gcm(modname,abort_message,1)
185    ALLOCATE(bpnc(nlevnc), stat = error)
186    IF (error /= 0) CALL abort_gcm(modname,abort_message,1)
187    apnc=0.;bpnc=0.
188
189    ALLOCATE(alpha_pcor(llm), stat = error)
190    IF (error /= 0) CALL abort_gcm(modname,abort_message,1)
191    ALLOCATE(alpha_u(ip1jmp1), stat = error)
192    IF (error /= 0) CALL abort_gcm(modname,abort_message,1)
193    ALLOCATE(alpha_v(ip1jm), stat = error)
194    IF (error /= 0) CALL abort_gcm(modname,abort_message,1)
195    ALLOCATE(alpha_T(ip1jmp1), stat = error)
196    IF (error /= 0) CALL abort_gcm(modname,abort_message,1)
197    ALLOCATE(alpha_Q(ip1jmp1), stat = error)
198    IF (error /= 0) CALL abort_gcm(modname,abort_message,1)
199    ALLOCATE(alpha_P(ip1jmp1), stat = error)
200    IF (error /= 0) CALL abort_gcm(modname,abort_message,1)
201    alpha_u=0.;alpha_v=0;alpha_T=0;alpha_Q=0;alpha_P=0
202   
203    IF (guide_u) THEN
204        ALLOCATE(unat1(iip1,jjp1,nlevnc), stat = error)
205        IF (error /= 0) CALL abort_gcm(modname,abort_message,1)
206        ALLOCATE(ugui1(ip1jmp1,llm), stat = error)
207        IF (error /= 0) CALL abort_gcm(modname,abort_message,1)
208        ALLOCATE(unat2(iip1,jjp1,nlevnc), stat = error)
209        IF (error /= 0) CALL abort_gcm(modname,abort_message,1)
210        ALLOCATE(ugui2(ip1jmp1,llm), stat = error)
211        IF (error /= 0) CALL abort_gcm(modname,abort_message,1)
212        unat1=0.;unat2=0.;ugui1=0.;ugui2=0.
213    ENDIF
214
215    IF (guide_T) THEN
216        ALLOCATE(tnat1(iip1,jjp1,nlevnc), stat = error)
217        IF (error /= 0) CALL abort_gcm(modname,abort_message,1)
218        ALLOCATE(tgui1(ip1jmp1,llm), stat = error)
219        IF (error /= 0) CALL abort_gcm(modname,abort_message,1)
220        ALLOCATE(tnat2(iip1,jjp1,nlevnc), stat = error)
221        IF (error /= 0) CALL abort_gcm(modname,abort_message,1)
222        ALLOCATE(tgui2(ip1jmp1,llm), stat = error)
223        IF (error /= 0) CALL abort_gcm(modname,abort_message,1)
224        tnat1=0.;tnat2=0.;tgui1=0.;tgui2=0.
225    ENDIF
226     
227    IF (guide_Q) THEN
228        ALLOCATE(qnat1(iip1,jjp1,nlevnc), stat = error)
229        IF (error /= 0) CALL abort_gcm(modname,abort_message,1)
230        ALLOCATE(qgui1(ip1jmp1,llm), stat = error)
231        IF (error /= 0) CALL abort_gcm(modname,abort_message,1)
232        ALLOCATE(qnat2(iip1,jjp1,nlevnc), stat = error)
233        IF (error /= 0) CALL abort_gcm(modname,abort_message,1)
234        ALLOCATE(qgui2(ip1jmp1,llm), stat = error)
235        IF (error /= 0) CALL abort_gcm(modname,abort_message,1)
236        qnat1=0.;qnat2=0.;qgui1=0.;qgui2=0.
237    ENDIF
238
239    IF (guide_v) THEN
240        ALLOCATE(vnat1(iip1,jjm,nlevnc), stat = error)
241        IF (error /= 0) CALL abort_gcm(modname,abort_message,1)
242        ALLOCATE(vgui1(ip1jm,llm), stat = error)
243        IF (error /= 0) CALL abort_gcm(modname,abort_message,1)
244        ALLOCATE(vnat2(iip1,jjm,nlevnc), stat = error)
245        IF (error /= 0) CALL abort_gcm(modname,abort_message,1)
246        ALLOCATE(vgui2(ip1jm,llm), stat = error)
247        IF (error /= 0) CALL abort_gcm(modname,abort_message,1)
248        vnat1=0.;vnat2=0.;vgui1=0.;vgui2=0.
249    ENDIF
250
251    IF (guide_plevs.EQ.2) THEN
252        ALLOCATE(pnat1(iip1,jjp1,nlevnc), stat = error)
253        IF (error /= 0) CALL abort_gcm(modname,abort_message,1)
254        ALLOCATE(pnat2(iip1,jjp1,nlevnc), stat = error)
255        IF (error /= 0) CALL abort_gcm(modname,abort_message,1)
256        pnat1=0.;pnat2=0.;
257    ENDIF
258
259    IF (guide_P.OR.guide_plevs.EQ.1) THEN
260        ALLOCATE(psnat1(iip1,jjp1), stat = error)
261        IF (error /= 0) CALL abort_gcm(modname,abort_message,1)
262        ALLOCATE(psnat2(iip1,jjp1), stat = error)
263        IF (error /= 0) CALL abort_gcm(modname,abort_message,1)
264        psnat1=0.;psnat2=0.;
265    ENDIF
266    IF (guide_P) THEN
267        ALLOCATE(psgui2(ip1jmp1), stat = error)
268        IF (error /= 0) CALL abort_gcm(modname,abort_message,1)
269        ALLOCATE(psgui1(ip1jmp1), stat = error)
270        IF (error /= 0) CALL abort_gcm(modname,abort_message,1)
271        psgui1=0.;psgui2=0.
272    ENDIF
273
274! ---------------------------------------------
275!   Lecture du premier etat de guidage.
276! ---------------------------------------------
277    IF (guide_2D) THEN
278        CALL guide_read2D(1)
279    ELSE
280        CALL guide_read(1)
281    ENDIF
282    IF (guide_v) vnat1=vnat2
283    IF (guide_u) unat1=unat2
284    IF (guide_T) tnat1=tnat2
285    IF (guide_Q) qnat1=qnat2
286    IF (guide_plevs.EQ.2) pnat1=pnat2
287    IF (guide_P.OR.guide_plevs.EQ.1) psnat1=psnat2
288
289  END SUBROUTINE guide_init
290
291!=======================================================================
292  SUBROUTINE guide_main(itau,ucov,vcov,teta,q,masse,ps)
293    use parallel
294    USE control_mod
295   
296    IMPLICIT NONE
297 
298    INCLUDE "dimensions.h"
299    INCLUDE "paramet.h"
300    INCLUDE "comconst.h"
301    INCLUDE "comvert.h"
302
303    ! Variables entree
304    INTEGER,                       INTENT(IN)    :: itau !pas de temps
305    REAL, DIMENSION (ip1jmp1,llm), INTENT(INOUT) :: ucov,teta,q,masse
306    REAL, DIMENSION (ip1jm,llm),   INTENT(INOUT) :: vcov
307    REAL, DIMENSION (ip1jmp1),     INTENT(INOUT) :: ps
308
309    ! Variables locales
310    LOGICAL, SAVE :: first=.TRUE.
311    LOGICAL       :: f_out ! sortie guidage
312    REAL, DIMENSION (ip1jmp1,llm) :: f_add ! var aux: champ de guidage
313    ! Variables pour fonction Exner (P milieu couche)
314    REAL, DIMENSION (iip1,jjp1,llm)    :: pk, pkf
315    REAL, DIMENSION (iip1,jjp1,llm)    :: alpha, beta
316    REAL, DIMENSION (iip1,jjp1)        :: pks   
317    REAL                               :: unskap
318    REAL, DIMENSION (ip1jmp1,llmp1)    :: p ! besoin si guide_P
319    ! Compteurs temps:
320    INTEGER, SAVE :: step_rea,count_no_rea,itau_test ! lecture guidage
321    REAL          :: ditau, dday_step
322    REAL          :: tau,reste ! position entre 2 etats de guidage
323    REAL, SAVE    :: factt ! pas de temps en fraction de jour
324   
325    INTEGER       :: i,j,l
326   
327    ijb_u=ij_begin ; ije_u=ij_end ; ijn_u=ije_u-ijb_u+1 
328    jjb_u=jj_begin ; jje_u=jj_end ; jjn_u=jje_u-jjb_u+1
329    ijb_v=ij_begin ; ije_v=ij_end ; ijn_v=ije_v-ijb_v+1   
330    jjb_v=jj_begin ; jje_v=jj_end ; jjn_v=jje_v-jjb_v+1
331    IF (pole_sud) THEN
332      ije_v=ij_end-iip1
333      jje_v=jj_end-1
334      ijn_v=ije_v-ijb_v+1
335      jjn_v=jje_v-jjb_v+1
336    ENDIF
337     
338     PRINT *,'---> on rentre dans guide_main'
339!    CALL AllGather_Field(ucov,ip1jmp1,llm)
340!    CALL AllGather_Field(vcov,ip1jm,llm)
341!    CALL AllGather_Field(teta,ip1jmp1,llm)
342!    CALL AllGather_Field(ps,ip1jmp1,1)
343!    CALL AllGather_Field(q,ip1jmp1,llm)
344   
345!-----------------------------------------------------------------------
346! Initialisations au premier passage
347!-----------------------------------------------------------------------
348
349    IF (first) THEN
350        first=.FALSE.
351        CALL guide_init
352        itau_test=1001
353        step_rea=1
354        count_no_rea=0
355! Calcul des constantes de rappel
356        factt=dtvr*iperiod/daysec
357        call tau2alpha(3,iip1,jjm ,factt,tau_min_v,tau_max_v,alpha_v)
358        call tau2alpha(2,iip1,jjp1,factt,tau_min_u,tau_max_u,alpha_u)
359        call tau2alpha(1,iip1,jjp1,factt,tau_min_T,tau_max_T,alpha_T)
360        call tau2alpha(1,iip1,jjp1,factt,tau_min_P,tau_max_P,alpha_P)
361        call tau2alpha(1,iip1,jjp1,factt,tau_min_Q,tau_max_Q,alpha_Q)
362! correction de rappel dans couche limite
363        if (guide_BL) then
364             alpha_pcor(:)=1.
365        else
366            do l=1,llm
367                alpha_pcor(l)=(1.+tanh((0.85-presnivs(l)/preff)/0.05))/2.
368            enddo
369        endif
370! ini_anal: etat initial egal au guidage       
371        IF (ini_anal) THEN
372            CALL guide_interp(ps,teta)
373            IF (guide_u) ucov(ijb_u:ije_u,:)=ugui2(ijb_u:ije_u,:)
374            IF (guide_v) vcov(ijb_v:ije_v,:)=ugui2(ijb_v:ije_v,:)
375            IF (guide_T) teta(ijb_u:ije_u,:)=tgui2(ijb_u:ije_u,:)
376            IF (guide_Q) q(ijb_u:ije_u,:)=qgui2(ijb_u:ije_u,:)
377            IF (guide_P) THEN
378                ps(ijb_u:ije_u)=psgui2(ijb_u:ije_u)
379                CALL pression_p(ip1jmp1,ap,bp,ps,p)
380                CALL massdair_p(p,masse)
381            ENDIF
382            RETURN
383        ENDIF
384! Verification structure guidage
385        IF (guide_u) THEN
386            CALL writefield_p('unat',unat1)
387            CALL writefield_p('ucov',RESHAPE(ucov,(/iip1,jjp1,llm/)))
388        ENDIF
389        IF (guide_T) THEN
390            CALL writefield_p('tnat',tnat1)
391            CALL writefield_p('teta',RESHAPE(teta,(/iip1,jjp1,llm/)))
392        ENDIF
393
394    ENDIF !first
395
396!-----------------------------------------------------------------------
397! Lecture des fichiers de guidage ?
398!-----------------------------------------------------------------------
399    IF (iguide_read.NE.0) THEN
400      ditau=real(itau)
401      dday_step=real(day_step)
402      IF (iguide_read.LT.0) THEN
403          tau=ditau/dday_step/REAL(iguide_read)
404      ELSE
405          tau=REAL(iguide_read)*ditau/dday_step
406      ENDIF
407      reste=tau-AINT(tau)
408      IF (reste.EQ.0.) THEN
409          IF (itau_test.EQ.itau) THEN
410              write(*,*)'deuxieme passage de advreel a itau=',itau
411              stop
412          ELSE
413              IF (guide_v) vnat1(:,jjb_v:jje_v,:)=vnat2(:,jjb_v:jje_v,:)
414              IF (guide_u) unat1(:,jjb_u:jje_u,:)=unat2(:,jjb_u:jje_u,:)
415              IF (guide_T) tnat1(:,jjb_u:jje_u,:)=tnat2(:,jjb_u:jje_u,:)
416              IF (guide_Q) qnat1(:,jjb_u:jje_u,:)=qnat2(:,jjb_u:jje_u,:)
417              IF (guide_plevs.EQ.2) pnat1(:,jjb_u:jje_u,:)=pnat2(:,jjb_u:jje_u,:)
418              IF (guide_P.OR.guide_plevs.EQ.1) psnat1(:,jjb_u:jje_u)=psnat2(:,jjb_u:jje_u)
419              step_rea=step_rea+1
420              itau_test=itau
421              print*,'Lecture fichiers guidage, pas ',step_rea, &
422                    'apres ',count_no_rea,' non lectures'
423              IF (guide_2D) THEN
424                  CALL guide_read2D(step_rea)
425              ELSE
426                  CALL guide_read(step_rea)
427              ENDIF
428              count_no_rea=0
429          ENDIF
430      ELSE
431        count_no_rea=count_no_rea+1
432
433      ENDIF
434    ENDIF !iguide_read=0
435
436!-----------------------------------------------------------------------
437! Interpolation et conversion des champs de guidage
438!-----------------------------------------------------------------------
439    IF (MOD(itau,iguide_int).EQ.0) THEN
440        CALL guide_interp(ps,teta)
441    ENDIF
442! Repartition entre 2 etats de guidage
443    IF (iguide_read.NE.0) THEN
444        tau=reste
445    ELSE
446        tau=1.
447    ENDIF
448
449!-----------------------------------------------------------------------
450!   Ajout des champs de guidage
451!-----------------------------------------------------------------------
452! Sauvegarde du guidage?
453    f_out=((MOD(itau,iguide_sav).EQ.0).AND.guide_sav) 
454    IF (f_out) THEN
455!       Calcul niveaux pression milieu de couches
456        CALL pression_p( ip1jmp1, ap, bp, ps, p )
457        if (pressure_exner) then
458          CALL exner_hyb_p(ip1jmp1,ps,p,alpha,beta,pks,pk,pkf)
459        else
460          CALL exner_milieu_p(ip1jmp1,ps,p,beta,pks,pk,pkf)
461        endif
462        unskap=1./kappa
463        DO l = 1, llm
464            DO j=jjb_u,jje_u
465                DO i =1, iip1
466                    p(i+(j-1)*iip1,l) = preff * ( pk(i,j,l)/cpp) ** unskap
467                ENDDO
468            ENDDO
469        ENDDO
470        CALL guide_out("P",jjp1,llm,p(1:ip1jmp1,1:llm),1.)
471    ENDIF
472   
473    if (guide_u) then
474        if (guide_add) then
475           f_add(ijb_u:ije_u,:)=(1.-tau)*ugui1(ijb_u:ije_u,:)+tau*ugui2(ijb_u:ije_u,:)
476        else
477           f_add(ijb_u:ije_u,:)=(1.-tau)*ugui1(ijb_u:ije_u,:)+tau*ugui2(ijb_u:ije_u,:)-ucov(ijb_u:ije_u,:)
478        endif
479
480        if (guide_zon) CALL guide_zonave(1,jjp1,llm,f_add)
481        CALL guide_addfield(ip1jmp1,llm,f_add,alpha_u)
482        IF (f_out) CALL guide_out("U",jjp1,llm,f_add(:,:),factt)
483        ucov(ijb_u:ije_u,:)=ucov(ijb_u:ije_u,:)+f_add(ijb_u:ije_u,:)
484    endif
485
486    if (guide_T) then
487        if (guide_add) then
488           f_add(ijb_u:ije_u,:)=(1.-tau)*tgui1(ijb_u:ije_u,:)+tau*tgui2(ijb_u:ije_u,:)
489        else
490           f_add(ijb_u:ije_u,:)=(1.-tau)*tgui1(ijb_u:ije_u,:)+tau*tgui2(ijb_u:ije_u,:)-teta(ijb_u:ije_u,:)
491        endif
492        if (guide_zon) CALL guide_zonave(2,jjp1,llm,f_add)
493        CALL guide_addfield(ip1jmp1,llm,f_add,alpha_T)
494        IF (f_out) CALL guide_out("T",jjp1,llm,f_add(:,:),factt)
495        teta(ijb_u:ije_u,:)=teta(ijb_u:ije_u,:)+f_add(ijb_u:ije_u,:)
496    endif
497
498    if (guide_P) then
499        if (guide_add) then
500           f_add(ijb_u:ije_u,1)=(1.-tau)*psgui1(ijb_u:ije_u)+tau*psgui2(ijb_u:ije_u)
501        else
502           f_add(ijb_u:ije_u,1)=(1.-tau)*psgui1(ijb_u:ije_u)+tau*psgui2(ijb_u:ije_u)-ps(ijb_u:ije_u)
503        endif
504        if (guide_zon) CALL guide_zonave(2,jjp1,1,f_add(1:ip1jmp1,1))
505        CALL guide_addfield(ip1jmp1,1,f_add(1:ip1jmp1,1),alpha_P)
506        IF (f_out) CALL guide_out("SP",jjp1,1,f_add(1:ip1jmp1,1),factt)
507        ps(ijb_u:ije_u)=ps(ijb_u:ije_u)+f_add(ijb_u:ije_u,1)
508        CALL pression_p(ip1jmp1,ap,bp,ps,p)
509        CALL massdair_p(p,masse)
510    endif
511
512    if (guide_Q) then
513        if (guide_add) then
514           f_add(ijb_u:ije_u,:)=(1.-tau)*qgui1(ijb_u:ije_u,:)+tau*qgui2(ijb_u:ije_u,:)
515        else
516           f_add(ijb_u:ije_u,:)=(1.-tau)*qgui1(ijb_u:ije_u,:)+tau*qgui2(ijb_u:ije_u,:)-q(ijb_u:ije_u,:)
517        endif
518        if (guide_zon) CALL guide_zonave(2,jjp1,llm,f_add)
519        CALL guide_addfield(ip1jmp1,llm,f_add,alpha_Q)
520        IF (f_out) CALL guide_out("Q",jjp1,llm,f_add(:,:),factt)
521        q(ijb_u:ije_u,:)=q(ijb_u:ije_u,:)+f_add(ijb_u:ije_u,:)
522    endif
523
524    if (guide_v) then
525        if (guide_add) then
526           f_add(ijb_v:ije_v,:)=(1.-tau)*vgui1(ijb_v:ije_v,:)+tau*vgui2(ijb_v:ije_v,:)
527        else
528           f_add(ijb_v:ije_v,:)=(1.-tau)*vgui1(ijb_v:ije_v,:)+tau*vgui2(ijb_v:ije_v,:)-vcov(ijb_v:ije_v,:)
529        endif
530       
531        if (guide_zon) CALL guide_zonave(2,jjm,llm,f_add(1:ip1jm,:))
532        CALL guide_addfield(ip1jm,llm,f_add(1:ip1jm,:),alpha_v)
533        IF (f_out) CALL guide_out("V",jjm,llm,f_add(1:ip1jm,:),factt)
534        vcov(ijb_v:ije_v,:)=vcov(ijb_v:ije_v,:)+f_add(ijb_v:ije_v,:)
535    endif
536
537  END SUBROUTINE guide_main
538
539!=======================================================================
540  SUBROUTINE guide_addfield(hsize,vsize,field,alpha)
541! field1=a*field1+alpha*field2
542
543    IMPLICIT NONE
544    INCLUDE "dimensions.h"
545    INCLUDE "paramet.h"
546
547    ! input variables
548    INTEGER,                      INTENT(IN)    :: hsize
549    INTEGER,                      INTENT(IN)    :: vsize
550    REAL, DIMENSION(hsize),       INTENT(IN)    :: alpha
551    REAL, DIMENSION(hsize,vsize), INTENT(INOUT) :: field
552
553    ! Local variables
554    INTEGER :: l
555
556    IF (hsize==ip1jm) THEN
557      do l=1,vsize
558        field(ijb_v:ije_v,l)=alpha(ijb_v:ije_v)*field(ijb_v:ije_v,l)*alpha_pcor(l)
559      enddo
560    ELSE
561      do l=1,vsize
562        field(ijb_u:ije_u,l)=alpha(ijb_u:ije_u)*field(ijb_u:ije_u,l)*alpha_pcor(l)
563      enddo
564    ENDIF   
565
566  END SUBROUTINE guide_addfield
567
568!=======================================================================
569  SUBROUTINE guide_zonave(typ,hsize,vsize,field)
570
571    IMPLICIT NONE
572
573    INCLUDE "dimensions.h"
574    INCLUDE "paramet.h"
575    INCLUDE "comgeom.h"
576    INCLUDE "comconst.h"
577   
578    ! input/output variables
579    INTEGER,                           INTENT(IN)    :: typ
580    INTEGER,                           INTENT(IN)    :: vsize
581    INTEGER,                           INTENT(IN)    :: hsize
582    REAL, DIMENSION(hsize*iip1,vsize), INTENT(INOUT) :: field
583
584    ! Local variables
585    LOGICAL, SAVE                :: first=.TRUE.
586    INTEGER, DIMENSION (2), SAVE :: imin, imax ! averaging domain
587    INTEGER                      :: i,j,l,ij
588    REAL, DIMENSION (iip1)       :: lond       ! longitude in Deg.
589    REAL, DIMENSION (hsize,vsize):: fieldm     ! zon-averaged field
590
591    IF (first) THEN
592        first=.FALSE.
593!Compute domain for averaging
594        lond=rlonu*180./pi
595        imin(1)=1;imax(1)=iip1;
596        imin(2)=1;imax(2)=iip1;
597        IF (guide_reg) THEN
598            DO i=1,iim
599                IF (lond(i).LT.lon_min_g) imin(1)=i
600                IF (lond(i).LE.lon_max_g) imax(1)=i
601            ENDDO
602            lond=rlonv*180./pi
603            DO i=1,iim
604                IF (lond(i).LT.lon_min_g) imin(2)=i
605                IF (lond(i).LE.lon_max_g) imax(2)=i
606            ENDDO
607        ENDIF
608    ENDIF
609
610    fieldm=0.
611   
612    IF (hsize==jjm) THEN
613      DO l=1,vsize
614      ! Compute zonal average
615          DO j=jjb_v,jje_v
616              DO i=imin(typ),imax(typ)
617                  ij=(j-1)*iip1+i
618                  fieldm(j,l)=fieldm(j,l)+field(ij,l)
619              ENDDO
620          ENDDO
621          fieldm(:,l)=fieldm(:,l)/REAL(imax(typ)-imin(typ)+1)
622    ! Compute forcing
623          DO j=jjb_v,jje_v
624              DO i=1,iip1
625                  ij=(j-1)*iip1+i
626                  field(ij,l)=fieldm(j,l)
627              ENDDO
628          ENDDO
629      ENDDO
630    ELSE
631      DO l=1,vsize
632      ! Compute zonal average
633          DO j=jjb_v,jje_v
634              DO i=imin(typ),imax(typ)
635                  ij=(j-1)*iip1+i
636                  fieldm(j,l)=fieldm(j,l)+field(ij,l)
637              ENDDO
638          ENDDO
639          fieldm(:,l)=fieldm(:,l)/REAL(imax(typ)-imin(typ)+1)
640    ! Compute forcing
641          DO j=jjb_u,jje_u
642              DO i=1,iip1
643                  ij=(j-1)*iip1+i
644                  field(ij,l)=fieldm(j,l)
645              ENDDO
646          ENDDO
647      ENDDO
648    ENDIF   
649
650  END SUBROUTINE guide_zonave
651
652!=======================================================================
653  SUBROUTINE guide_interp(psi,teta)
654  USE parallel
655  USE mod_hallo
656  USE Bands
657  IMPLICIT NONE
658
659  include "dimensions.h"
660  include "paramet.h"
661  include "comvert.h"
662  include "comgeom2.h"
663  include "comconst.h"
664
665  REAL, DIMENSION (iip1,jjp1),     INTENT(IN) :: psi ! Psol gcm
666  REAL, DIMENSION (iip1,jjp1,llm), INTENT(IN) :: teta ! Temp. Pot. gcm
667
668  LOGICAL, SAVE                      :: first=.TRUE.
669  ! Variables pour niveaux pression:
670  REAL, DIMENSION (iip1,jjp1,nlevnc) :: plnc1,plnc2 !niveaux pression guidage
671  REAL, DIMENSION (iip1,jjp1,llm)    :: plunc,plsnc !niveaux pression modele
672  REAL, DIMENSION (iip1,jjm,llm)     :: plvnc       !niveaux pression modele
673  REAL, DIMENSION (iip1,jjp1,llmp1)  :: p           ! pression intercouches
674  REAL, DIMENSION (iip1,jjp1,llm)    :: pls, pext   ! var intermediaire
675  REAL, DIMENSION (iip1,jjp1,llm)    :: pbarx
676  REAL, DIMENSION (iip1,jjm,llm)     :: pbary
677  ! Variables pour fonction Exner (P milieu couche)
678  REAL, DIMENSION (iip1,jjp1,llm)    :: pk, pkf
679  REAL, DIMENSION (iip1,jjp1,llm)    :: alpha, beta
680  REAL, DIMENSION (iip1,jjp1)        :: pks   
681  REAL                               :: unskap
682  ! Pression de vapeur saturante
683  REAL, DIMENSION (ip1jmp1,llm)      :: qsat
684  !Variables intermediaires interpolation
685  REAL, DIMENSION (iip1,jjp1,llm)    :: zu1,zu2
686  REAL, DIMENSION (iip1,jjm,llm)     :: zv1,zv2
687 
688  INTEGER                            :: i,j,l,ij
689  TYPE(Request) :: Req 
690
691    print *,'Guide: conversion variables guidage'
692! -----------------------------------------------------------------
693! Calcul des niveaux de pression champs guidage (pour T et Q)
694! -----------------------------------------------------------------
695    IF (guide_plevs.EQ.0) THEN
696        DO l=1,nlevnc
697            DO j=jjb_u,jje_u
698                DO i=1,iip1
699                    plnc2(i,j,l)=apnc(l)
700                    plnc1(i,j,l)=apnc(l)
701               ENDDO
702            ENDDO
703        ENDDO
704    ENDIF   
705
706    if (first) then
707        first=.FALSE.
708        print*,'Guide: verification ordre niveaux verticaux'
709        print*,'LMDZ :'
710        do l=1,llm
711            print*,'PL(',l,')=',(ap(l)+ap(l+1))/2. &
712                  +psi(1,jje_u)*(bp(l)+bp(l+1))/2.
713        enddo
714        print*,'Fichiers guidage'
715        SELECT CASE (guide_plevs)
716        CASE (0)
717            do l=1,nlevnc
718                 print*,'PL(',l,')=',plnc2(1,jjb_u,l)
719            enddo
720        CASE (1)
721            DO l=1,nlevnc
722                 print*,'PL(',l,')=',apnc(l)+bpnc(l)*psnat2(i,jjb_u)
723             ENDDO
724        CASE (2)
725            do l=1,nlevnc
726                 print*,'PL(',l,')=',pnat2(1,jjb_u,l)
727            enddo
728        END SELECT
729        print *,'inversion de l''ordre: invert_p=',invert_p
730        if (guide_u) then
731            do l=1,nlevnc
732                print*,'U(',l,')=',unat2(1,jjb_u,l)
733            enddo
734        endif
735        if (guide_T) then
736            do l=1,nlevnc
737                print*,'T(',l,')=',tnat2(1,jjb_u,l)
738            enddo
739        endif
740    endif
741   
742! -----------------------------------------------------------------
743! Calcul niveaux pression modele
744! -----------------------------------------------------------------
745
746!    ....  Calcul de pls , pression au milieu des couches ,en Pascals
747    IF (guide_plevs.EQ.1) THEN
748        DO l=1,llm
749            DO j=jjb_u,jje_u
750                DO i =1, iip1
751                    pls(i,j,l)=(ap(l)+ap(l+1))/2.+psi(i,j)*(bp(l)+bp(l+1))/2.
752                ENDDO
753            ENDDO
754        ENDDO
755    ELSE
756        CALL pression_p( ip1jmp1, ap, bp, psi, p )
757        if (pressure_exner) then
758          CALL exner_hyb_p(ip1jmp1,psi,p,alpha,beta,pks,pk,pkf)
759        else
760          CALL exner_milieu_p(ip1jmp1,psi,p,beta,pks,pk,pkf)
761        endif
762        unskap=1./kappa
763        DO l = 1, llm
764            DO j=jjb_u,jje_u
765                DO i =1, iip1
766                    pls(i,j,l) = preff * ( pk(i,j,l)/cpp) ** unskap
767                ENDDO
768            ENDDO
769        ENDDO
770    ENDIF
771
772!   calcul des pressions pour les grilles u et v
773    do l=1,llm
774        do j=jjb_u,jje_u
775            do i=1,iip1
776                pext(i,j,l)=pls(i,j,l)*aire(i,j)
777            enddo
778        enddo
779    enddo
780
781     CALL Register_SwapFieldHallo(pext,pext,ip1jmp1,llm,jj_Nb_caldyn,1,2,Req)
782     CALL SendRequest(Req)
783     CALL WaitRequest(Req)
784
785     call massbar_p(pext, pbarx, pbary )
786    do l=1,llm
787        do j=jjb_u,jje_u
788            do i=1,iip1
789                plunc(i,j,l)=pbarx(i,j,l)/aireu(i,j)
790                plsnc(i,j,l)=pls(i,j,l)
791            enddo
792        enddo
793    enddo
794    do l=1,llm
795        do j=jjb_v,jje_v
796            do i=1,iip1
797                plvnc(i,j,l)=pbary(i,j,l)/airev(i,j)
798            enddo
799        enddo
800    enddo
801
802! -----------------------------------------------------------------
803! Interpolation verticale champs guidage sur niveaux modele
804! Conversion en variables gcm (ucov, vcov...)
805! -----------------------------------------------------------------
806    if (guide_P) then
807        do j=jjb_u,jje_u
808            do i=1,iim
809                ij=(j-1)*iip1+i
810                psgui1(ij)=psnat1(i,j)
811                psgui2(ij)=psnat2(i,j)
812            enddo
813            psgui1(iip1*j)=psnat1(1,j)
814            psgui2(iip1*j)=psnat2(1,j)
815        enddo
816    endif
817
818    IF (guide_T) THEN
819        ! Calcul des nouvelles valeurs des niveaux de pression du guidage
820        IF (guide_plevs.EQ.1) THEN
821            DO l=1,nlevnc
822                DO j=jjb_u,jje_u
823                    DO i=1,iip1
824                        plnc2(i,j,l)=apnc(l)+bpnc(l)*psnat2(i,j)
825                        plnc1(i,j,l)=apnc(l)+bpnc(l)*psnat1(i,j)
826                    ENDDO
827                ENDDO
828            ENDDO
829        ELSE IF (guide_plevs.EQ.2) THEN
830            DO l=1,nlevnc
831                DO j=jjb_u,jje_u
832                    DO i=1,iip1
833                        plnc2(i,j,l)=pnat2(i,j,l)
834                        plnc1(i,j,l)=pnat1(i,j,l)
835                    ENDDO
836                ENDDO
837            ENDDO
838        ENDIF
839
840        ! Interpolation verticale
841        CALL pres2lev(tnat1(:,jjb_u:jje_u,:),zu1(:,jjb_u:jje_u,:),nlevnc,llm,           &
842                    plnc1(:,jjb_u:jje_u,:),plsnc(:,jjb_u:jje_u,:),iip1,jjn_u,invert_p)
843        CALL pres2lev(tnat2(:,jjb_u:jje_u,:),zu2(:,jjb_u:jje_u,:),nlevnc,llm,           &
844                    plnc2(:,jjb_u:jje_u,:),plsnc(:,jjb_u:jje_u,:),iip1,jjn_u,invert_p)
845
846        ! Conversion en variables GCM
847        do l=1,llm
848            do j=jjb_u,jje_u
849                IF (guide_teta) THEN
850                    do i=1,iim
851                        ij=(j-1)*iip1+i
852                        tgui1(ij,l)=zu1(i,j,l)
853                        tgui2(ij,l)=zu2(i,j,l)
854                    enddo
855                ELSE
856                    do i=1,iim
857                        ij=(j-1)*iip1+i
858                        tgui1(ij,l)=zu1(i,j,l)*cpp/pk(i,j,l)
859                        tgui2(ij,l)=zu2(i,j,l)*cpp/pk(i,j,l)
860                    enddo
861                ENDIF
862                tgui1(j*iip1,l)=tgui1((j-1)*iip1+1,l)   
863                tgui2(j*iip1,l)=tgui2((j-1)*iip1+1,l)   
864            enddo
865            do i=1,iip1
866                tgui1(i,l)=tgui1(1,l)
867                tgui1(ip1jm+i,l)=tgui1(ip1jm+1,l)
868                tgui2(i,l)=tgui2(1,l)
869                tgui2(ip1jm+i,l)=tgui2(ip1jm+1,l)
870            enddo
871        enddo
872    ENDIF
873
874    IF (guide_Q) THEN
875        ! Calcul des nouvelles valeurs des niveaux de pression du guidage
876        IF (guide_plevs.EQ.1) THEN
877            DO l=1,nlevnc
878                DO j=jjb_u,jje_u
879                    DO i=1,iip1
880                        plnc2(i,j,l)=apnc(l)+bpnc(l)*psnat2(i,j)
881                        plnc1(i,j,l)=apnc(l)+bpnc(l)*psnat1(i,j)
882                    ENDDO
883                ENDDO
884            ENDDO
885        ELSE IF (guide_plevs.EQ.2) THEN
886            DO l=1,nlevnc
887                DO j=jjb_u,jje_u
888                    DO i=1,iip1
889                        plnc2(i,j,l)=pnat2(i,j,l)
890                        plnc1(i,j,l)=pnat1(i,j,l)
891                    ENDDO
892                ENDDO
893            ENDDO
894        ENDIF
895
896        ! Interpolation verticale
897        CALL pres2lev(qnat1(:,jjb_u:jje_u,:),zu1(:,jjb_u:jje_u,:),nlevnc,llm,             &
898                      plnc1(:,jjb_u:jje_u,:),plsnc(:,jjb_u:jje_u,:),iip1,jjn_u,invert_p)
899        CALL pres2lev(qnat2(:,jjb_u:jje_u,:),zu2(:,jjb_u:jje_u,:),nlevnc,llm,             &
900                      plnc2(:,jjb_u:jje_u,:),plsnc(:,jjb_u:jje_u,:),iip1,jjn_u,invert_p)
901
902        ! Conversion en variables GCM
903        ! On suppose qu'on a la bonne variable dans le fichier de guidage:
904        ! Hum.Rel si guide_hr, Hum.Spec. sinon.
905        do l=1,llm
906            do j=jjb_u,jje_u
907                do i=1,iim
908                    ij=(j-1)*iip1+i
909                    qgui1(ij,l)=zu1(i,j,l)
910                    qgui2(ij,l)=zu2(i,j,l)
911                enddo
912                qgui1(j*iip1,l)=qgui1((j-1)*iip1+1,l)   
913                qgui2(j*iip1,l)=qgui2((j-1)*iip1+1,l)   
914            enddo
915            do i=1,iip1
916                qgui1(i,l)=qgui1(1,l)
917                qgui1(ip1jm+i,l)=qgui1(ip1jm+1,l)
918                qgui2(i,l)=qgui2(1,l)
919                qgui2(ip1jm+i,l)=qgui2(ip1jm+1,l)
920            enddo
921        enddo
922        IF (guide_hr) THEN
923            CALL q_sat(iip1*jjn_u*llm,teta(:,jjb_u:jje_u,:)*pk(:,jjb_u:jje_u,:)/cpp,       &
924                       plsnc(:,jjb_u:jje_u,:),qsat(ijb_u:ije_u,:))
925            qgui1(ijb_u:ije_u,:)=qgui1(ijb_u:ije_u,:)*qsat(ijb_u:ije_u,:)*0.01 !hum. rel. en %
926            qgui2(ijb_u:ije_u,:)=qgui2(ijb_u:ije_u,:)*qsat(ijb_u:ije_u,:)*0.01
927        ENDIF
928    ENDIF
929
930    IF (guide_u) THEN
931        ! Calcul des nouvelles valeurs des niveaux de pression du guidage
932        IF (guide_plevs.EQ.1) THEN
933            DO l=1,nlevnc
934                DO j=jjb_u,jje_u
935                    DO i=1,iim
936                        plnc2(i,j,l)=apnc(l)+bpnc(l)*(psnat2(i,j)*aire(i,j)*alpha1p2(i,j) &
937                       &           +psnat2(i+1,j)*aire(i+1,j)*alpha3p4(i+1,j))/aireu(i,j)
938                        plnc1(i,j,l)=apnc(l)+bpnc(l)*(psnat1(i,j)*aire(i,j)*alpha1p2(i,j) &
939                       &           +psnat1(i+1,j)*aire(i+1,j)*alpha3p4(i+1,j))/aireu(i,j)
940                    ENDDO
941                    plnc2(iip1,j,l)=plnc2(1,j,l)
942                    plnc1(iip1,j,l)=plnc1(1,j,l)
943                ENDDO
944            ENDDO
945        ELSE IF (guide_plevs.EQ.2) THEN
946            DO l=1,nlevnc
947                DO j=jjb_u,jje_u
948                    DO i=1,iim
949                        plnc2(i,j,l)=(pnat2(i,j,l)*aire(i,j)*alpha1p2(i,j) &
950                       & +pnat2(i+1,j,l)*aire(i,j)*alpha3p4(i+1,j))/aireu(i,j)
951                        plnc1(i,j,l)=(pnat1(i,j,l)*aire(i,j)*alpha1p2(i,j) &
952                       & +pnat1(i+1,j,l)*aire(i,j)*alpha3p4(i+1,j))/aireu(i,j)
953                    ENDDO
954                    plnc2(iip1,j,l)=plnc2(1,j,l)
955                    plnc1(iip1,j,l)=plnc1(1,j,l)
956                ENDDO
957            ENDDO
958        ENDIF
959       
960        ! Interpolation verticale
961        CALL pres2lev(unat1(:,jjb_u:jje_u,:),zu1(:,jjb_u:jje_u,:),nlevnc,llm,            &
962                      plnc1(:,jjb_u:jje_u,:),plunc(:,jjb_u:jje_u,:),iip1,jjn_u,invert_p)
963        CALL pres2lev(unat2(:,jjb_u:jje_u,:),zu2(:,jjb_u:jje_u,:),nlevnc,llm,            &
964                      plnc2(:,jjb_u:jje_u,:),plunc(:,jjb_u:jje_u,:),iip1,jjn_u,invert_p)
965
966        ! Conversion en variables GCM
967        do l=1,llm
968            do j=jjb_u,jje_u
969                do i=1,iim
970                    ij=(j-1)*iip1+i
971                    ugui1(ij,l)=zu1(i,j,l)*cu(i,j)
972                    ugui2(ij,l)=zu2(i,j,l)*cu(i,j)
973                enddo
974                ugui1(j*iip1,l)=ugui1((j-1)*iip1+1,l)   
975                ugui2(j*iip1,l)=ugui2((j-1)*iip1+1,l)   
976            enddo
977            do i=1,iip1
978                ugui1(i,l)=0.
979                ugui1(ip1jm+i,l)=0.
980                ugui2(i,l)=0.
981                ugui2(ip1jm+i,l)=0.
982            enddo
983        enddo
984    ENDIF
985   
986    IF (guide_v) THEN
987        ! Calcul des nouvelles valeurs des niveaux de pression du guidage
988        IF (guide_plevs.EQ.1) THEN
989         CALL Register_SwapFieldHallo(psnat1,psnat1,ip1jmp1,1,jj_Nb_caldyn,1,2,Req)
990         CALL SendRequest(Req)
991         CALL WaitRequest(Req)
992         CALL Register_SwapFieldHallo(psnat2,psnat2,ip1jmp1,1,jj_Nb_caldyn,1,2,Req)
993         CALL SendRequest(Req)
994         CALL WaitRequest(Req)
995            DO l=1,nlevnc
996                DO j=jjb_v,jje_v
997                    DO i=1,iip1
998                        plnc2(i,j,l)=apnc(l)+bpnc(l)*(psnat2(i,j)*aire(i,j)*alpha2p3(i,j) &
999                       &           +psnat2(i,j+1)*aire(i,j+1)*alpha1p4(i,j+1))/airev(i,j)
1000                        plnc1(i,j,l)=apnc(l)+bpnc(l)*(psnat1(i,j)*aire(i,j)*alpha2p3(i,j) &
1001                       &           +psnat1(i,j+1)*aire(i,j+1)*alpha1p4(i,j+1))/airev(i,j)
1002                    ENDDO
1003                ENDDO
1004            ENDDO
1005        ELSE IF (guide_plevs.EQ.2) THEN
1006         CALL Register_SwapFieldHallo(pnat1,pnat1,ip1jmp1,llm,jj_Nb_caldyn,1,2,Req)
1007         CALL SendRequest(Req)
1008         CALL WaitRequest(Req)
1009         CALL Register_SwapFieldHallo(pnat2,pnat2,ip1jmp1,llm,jj_Nb_caldyn,1,2,Req)
1010         CALL SendRequest(Req)
1011         CALL WaitRequest(Req)
1012            DO l=1,nlevnc
1013                DO j=jjb_v,jje_v
1014                    DO i=1,iip1
1015                        plnc2(i,j,l)=(pnat2(i,j,l)*aire(i,j)*alpha2p3(i,j) &
1016                       & +pnat2(i,j+1,l)*aire(i,j)*alpha1p4(i,j+1))/airev(i,j)
1017                        plnc1(i,j,l)=(pnat1(i,j,l)*aire(i,j)*alpha2p3(i,j) &
1018                       & +pnat1(i,j+1,l)*aire(i,j)*alpha1p4(i,j+1))/airev(i,j)
1019                    ENDDO
1020                ENDDO
1021            ENDDO
1022        ENDIF
1023        ! Interpolation verticale
1024        CALL pres2lev(vnat1(:,jjb_v:jje_v,:),zv1(:,jjb_v:jje_v,:),nlevnc,llm,             &
1025                      plnc1(:,jjb_v:jje_v,:),plvnc(:,jjb_v:jje_v,:),iip1,jjn_v,invert_p)
1026        CALL pres2lev(vnat2(:,jjb_v:jje_v,:),zv2(:,jjb_v:jje_v,:),nlevnc,llm,             &
1027                      plnc2(:,jjb_v:jje_v,:),plvnc(:,jjb_v:jje_v,:),iip1,jjn_v,invert_p)
1028        ! Conversion en variables GCM
1029        do l=1,llm
1030            do j=jjb_v,jje_v
1031                do i=1,iim
1032                    ij=(j-1)*iip1+i
1033                    vgui1(ij,l)=zv1(i,j,l)*cv(i,j)
1034                    vgui2(ij,l)=zv2(i,j,l)*cv(i,j)
1035                enddo
1036                vgui1(j*iip1,l)=vgui1((j-1)*iip1+1,l)   
1037                vgui2(j*iip1,l)=vgui2((j-1)*iip1+1,l)   
1038            enddo
1039        enddo
1040    ENDIF
1041   
1042
1043  END SUBROUTINE guide_interp
1044
1045!=======================================================================
1046  SUBROUTINE tau2alpha(typ,pim,pjm,factt,taumin,taumax,alpha)
1047
1048! Calcul des constantes de rappel alpha (=1/tau)
1049
1050    implicit none
1051
1052    include "dimensions.h"
1053    include "paramet.h"
1054    include "comconst.h"
1055    include "comgeom2.h"
1056    include "serre.h"
1057
1058! input arguments :
1059    INTEGER, INTENT(IN) :: typ    ! u(2),v(3), ou scalaire(1)
1060    INTEGER, INTENT(IN) :: pim,pjm ! dimensions en lat, lon
1061    REAL, INTENT(IN)    :: factt   ! pas de temps en fraction de jour
1062    REAL, INTENT(IN)    :: taumin,taumax
1063! output arguments:
1064    REAL, DIMENSION(pim,pjm), INTENT(OUT) :: alpha
1065 
1066!  local variables:
1067    LOGICAL, SAVE               :: first=.TRUE.
1068    REAL, SAVE                  :: gamma,dxdy_min,dxdy_max
1069    REAL, DIMENSION (iip1,jjp1) :: zdx,zdy
1070    REAL, DIMENSION (iip1,jjp1) :: dxdys,dxdyu
1071    REAL, DIMENSION (iip1,jjm)  :: dxdyv
1072    real dxdy_
1073    real zlat,zlon
1074    real alphamin,alphamax,xi
1075    integer i,j,ilon,ilat
1076
1077
1078    alphamin=factt/taumax
1079    alphamax=factt/taumin
1080    IF (guide_reg.OR.guide_add) THEN
1081        alpha=alphamax
1082!-----------------------------------------------------------------------
1083! guide_reg: alpha=alpha_min dans region, 0. sinon.
1084!-----------------------------------------------------------------------
1085        IF (guide_reg) THEN
1086            do j=1,pjm
1087                do i=1,pim
1088                    if (typ.eq.2) then
1089                       zlat=rlatu(j)*180./pi
1090                       zlon=rlonu(i)*180./pi
1091                    elseif (typ.eq.1) then
1092                       zlat=rlatu(j)*180./pi
1093                       zlon=rlonv(i)*180./pi
1094                    elseif (typ.eq.3) then
1095                       zlat=rlatv(j)*180./pi
1096                       zlon=rlonv(i)*180./pi
1097                    endif
1098                    alpha(i,j)=alphamax/16.* &
1099                              (1.+tanh((zlat-lat_min_g)/tau_lat))* &
1100                              (1.+tanh((lat_max_g-zlat)/tau_lat))* &
1101                              (1.+tanh((zlon-lon_min_g)/tau_lon))* &
1102                              (1.+tanh((lon_max_g-zlon)/tau_lon))
1103                enddo
1104            enddo
1105        ENDIF
1106    ELSE
1107!-----------------------------------------------------------------------
1108! Sinon, alpha varie entre alpha_min et alpha_max suivant le zoom.
1109!-----------------------------------------------------------------------
1110!Calcul de l'aire des mailles
1111        do j=2,jjm
1112            do i=2,iip1
1113               zdx(i,j)=0.5*(cu(i-1,j)+cu(i,j))/cos(rlatu(j))
1114            enddo
1115            zdx(1,j)=zdx(iip1,j)
1116        enddo
1117        do j=2,jjm
1118            do i=1,iip1
1119               zdy(i,j)=0.5*(cv(i,j-1)+cv(i,j))
1120            enddo
1121        enddo
1122        do i=1,iip1
1123            zdx(i,1)=zdx(i,2)
1124            zdx(i,jjp1)=zdx(i,jjm)
1125            zdy(i,1)=zdy(i,2)
1126            zdy(i,jjp1)=zdy(i,jjm)
1127        enddo
1128        do j=1,jjp1
1129            do i=1,iip1
1130               dxdys(i,j)=sqrt(zdx(i,j)*zdx(i,j)+zdy(i,j)*zdy(i,j))
1131            enddo
1132        enddo
1133        IF (typ.EQ.2) THEN
1134            do j=1,jjp1
1135                do i=1,iim
1136                   dxdyu(i,j)=0.5*(dxdys(i,j)+dxdys(i+1,j))
1137                enddo
1138                dxdyu(iip1,j)=dxdyu(1,j)
1139            enddo
1140        ENDIF
1141        IF (typ.EQ.3) THEN
1142            do j=1,jjm
1143                do i=1,iip1
1144                   dxdyv(i,j)=0.5*(dxdys(i,j)+dxdys(i,j+1))
1145                enddo
1146            enddo
1147        ENDIF
1148! Premier appel: calcul des aires min et max et de gamma.
1149        IF (first) THEN
1150            first=.FALSE.
1151            ! coordonnees du centre du zoom
1152            CALL coordij(clon,clat,ilon,ilat)
1153            ! aire de la maille au centre du zoom
1154            dxdy_min=dxdys(ilon,ilat)
1155            ! dxdy maximale de la maille
1156            dxdy_max=0.
1157            do j=1,jjp1
1158                do i=1,iip1
1159                     dxdy_max=max(dxdy_max,dxdys(i,j))
1160                enddo
1161            enddo
1162            ! Calcul de gamma
1163            if (abs(grossismx-1.).lt.0.1.or.abs(grossismy-1.).lt.0.1) then
1164                 print*,'ATTENTION modele peu zoome'
1165                 print*,'ATTENTION on prend une constante de guidage cste'
1166                 gamma=0.
1167            else
1168                gamma=(dxdy_max-2.*dxdy_min)/(dxdy_max-dxdy_min)
1169                print*,'gamma=',gamma
1170                if (gamma.lt.1.e-5) then
1171                  print*,'gamma =',gamma,'<1e-5'
1172                  stop
1173                endif
1174                gamma=log(0.5)/log(gamma)
1175                if (gamma4) then
1176                  gamma=min(gamma,4.)
1177                endif
1178                print*,'gamma=',gamma
1179            endif
1180        ENDIF !first
1181
1182        do j=1,pjm
1183            do i=1,pim
1184                if (typ.eq.1) then
1185                   dxdy_=dxdys(i,j)
1186                   zlat=rlatu(j)*180./pi
1187                elseif (typ.eq.2) then
1188                   dxdy_=dxdyu(i,j)
1189                   zlat=rlatu(j)*180./pi
1190                elseif (typ.eq.3) then
1191                   dxdy_=dxdyv(i,j)
1192                   zlat=rlatv(j)*180./pi
1193                endif
1194                if (abs(grossismx-1.).lt.0.1.or.abs(grossismy-1.).lt.0.1) then
1195                ! pour une grille reguliere, xi=xxx**0=1 -> alpha=alphamin
1196                    alpha(i,j)=alphamin
1197                else
1198                    xi=((dxdy_max-dxdy_)/(dxdy_max-dxdy_min))**gamma
1199                    xi=min(xi,1.)
1200                    if(lat_min_g.le.zlat .and. zlat.le.lat_max_g) then
1201                        alpha(i,j)=xi*alphamin+(1.-xi)*alphamax
1202                    else
1203                        alpha(i,j)=0.
1204                    endif
1205                endif
1206            enddo
1207        enddo
1208    ENDIF ! guide_reg
1209
1210  END SUBROUTINE tau2alpha
1211
1212!=======================================================================
1213  SUBROUTINE guide_read(timestep)
1214
1215    IMPLICIT NONE
1216
1217#include "netcdf.inc"
1218#include "dimensions.h"
1219#include "paramet.h"
1220
1221    INTEGER, INTENT(IN)   :: timestep
1222
1223    LOGICAL, SAVE         :: first=.TRUE.
1224! Identification fichiers et variables NetCDF:
1225    INTEGER, SAVE         :: ncidu,varidu,ncidv,varidv,ncidp,varidp
1226    INTEGER, SAVE         :: ncidQ,varidQ,ncidt,varidt,ncidps,varidps
1227    INTEGER               :: ncidpl,varidpl,varidap,varidbp
1228! Variables auxiliaires NetCDF:
1229    INTEGER, DIMENSION(4) :: start,count
1230    INTEGER               :: status,rcode
1231
1232! -----------------------------------------------------------------
1233! Premier appel: initialisation de la lecture des fichiers
1234! -----------------------------------------------------------------
1235    if (first) then
1236         ncidpl=-99
1237         print*,'Guide: ouverture des fichiers guidage '
1238! Ap et Bp si Niveaux de pression hybrides
1239         if (guide_plevs.EQ.1) then
1240             print *,'Lecture du guidage sur niveaux modele'
1241             rcode = nf90_open('apbp.nc', nf90_nowrite, ncidpl)
1242             rcode = nf90_inq_varid(ncidpl, 'AP', varidap)
1243             rcode = nf90_inq_varid(ncidpl, 'BP', varidbp)
1244             print*,'ncidpl,varidap',ncidpl,varidap
1245         endif
1246! Pression si guidage sur niveaux P variables
1247         if (guide_plevs.EQ.2) then
1248             rcode = nf90_open('P.nc', nf90_nowrite, ncidp)
1249             rcode = nf90_inq_varid(ncidp, 'PRES', varidp)
1250             print*,'ncidp,varidp',ncidp,varidp
1251             if (ncidpl.eq.-99) ncidpl=ncidp
1252         endif
1253! Vent zonal
1254         if (guide_u) then
1255             rcode = nf90_open('u.nc', nf90_nowrite, ncidu)
1256             rcode = nf90_inq_varid(ncidu, 'UWND', varidu)
1257             print*,'ncidu,varidu',ncidu,varidu
1258             if (ncidpl.eq.-99) ncidpl=ncidu
1259         endif
1260! Vent meridien
1261         if (guide_v) then
1262             rcode = nf90_open('v.nc', nf90_nowrite, ncidv)
1263             rcode = nf90_inq_varid(ncidv, 'VWND', varidv)
1264             print*,'ncidv,varidv',ncidv,varidv
1265             if (ncidpl.eq.-99) ncidpl=ncidv
1266         endif
1267! Temperature
1268         if (guide_T) then
1269             rcode = nf90_open('T.nc', nf90_nowrite, ncidt)
1270             rcode = nf90_inq_varid(ncidt, 'AIR', varidt)
1271             print*,'ncidT,varidT',ncidt,varidt
1272             if (ncidpl.eq.-99) ncidpl=ncidt
1273         endif
1274! Humidite
1275         if (guide_Q) then
1276             rcode = nf90_open('hur.nc', nf90_nowrite, ncidQ)
1277             rcode = nf90_inq_varid(ncidQ, 'RH', varidQ)
1278             print*,'ncidQ,varidQ',ncidQ,varidQ
1279             if (ncidpl.eq.-99) ncidpl=ncidQ
1280         endif
1281! Pression de surface
1282         if ((guide_P).OR.(guide_plevs.EQ.1)) then
1283             rcode = nf90_open('ps.nc', nf90_nowrite, ncidps)
1284             rcode = nf90_inq_varid(ncidps, 'SP', varidps)
1285             print*,'ncidps,varidps',ncidps,varidps
1286         endif
1287! Coordonnee verticale
1288         if (guide_plevs.EQ.0) then
1289              rcode = nf90_inq_varid(ncidpl, 'LEVEL', varidpl)
1290              IF (rcode.NE.0) rcode = nf90_inq_varid(ncidpl, 'PRESSURE', varidpl)
1291              print*,'ncidpl,varidpl',ncidpl,varidpl
1292         endif
1293! Coefs ap, bp pour calcul de la pression aux differents niveaux
1294         IF (guide_plevs.EQ.1) THEN
1295#ifdef NC_DOUBLE
1296             status=NF_GET_VARA_DOUBLE(ncidpl,varidap,1,nlevnc,apnc)
1297             status=NF_GET_VARA_DOUBLE(ncidpl,varidbp,1,nlevnc,bpnc)
1298#else
1299             status=NF_GET_VARA_REAL(ncidpl,varidap,1,nlevnc,apnc)
1300             status=NF_GET_VARA_REAL(ncidpl,varidbp,1,nlevnc,bpnc)
1301#endif
1302         ELSEIF (guide_plevs.EQ.0) THEN
1303#ifdef NC_DOUBLE
1304             status=NF_GET_VARA_DOUBLE(ncidpl,varidpl,1,nlevnc,apnc)
1305#else
1306             status=NF_GET_VARA_REAL(ncidpl,varidpl,1,nlevnc,apnc)
1307#endif
1308             apnc=apnc*100.! conversion en Pascals
1309             bpnc(:)=0.
1310         ENDIF
1311         first=.FALSE.
1312     ENDIF ! (first)
1313
1314! -----------------------------------------------------------------
1315!   lecture des champs u, v, T, Q, ps
1316! -----------------------------------------------------------------
1317
1318!  dimensions pour les champs scalaires et le vent zonal
1319     start(1)=1
1320     start(2)=1
1321     start(3)=1
1322     start(4)=timestep
1323
1324     count(1)=iip1
1325     count(2)=jjp1
1326     count(3)=nlevnc
1327     count(4)=1
1328
1329! Pression
1330     if (guide_plevs.EQ.2) then
1331#ifdef NC_DOUBLE
1332         status=NF_GET_VARA_DOUBLE(ncidp,varidp,start,count,pnat2)
1333#else
1334         status=NF_GET_VARA_REAL(ncidp,varidp,start,count,pnat2)
1335#endif
1336         IF (invert_y) THEN
1337           CALL invert_lat(iip1,jjp1,nlevnc,pnat2)
1338         ENDIF
1339     endif
1340
1341!  Vent zonal
1342     if (guide_u) then
1343#ifdef NC_DOUBLE
1344         status=NF_GET_VARA_DOUBLE(ncidu,varidu,start,count,unat2)
1345#else
1346         status=NF_GET_VARA_REAL(ncidu,varidu,start,count,unat2)
1347#endif
1348         IF (invert_y) THEN
1349           CALL invert_lat(iip1,jjp1,nlevnc,unat2)
1350         ENDIF
1351
1352     endif
1353
1354!  Temperature
1355     if (guide_T) then
1356#ifdef NC_DOUBLE
1357         status=NF_GET_VARA_DOUBLE(ncidt,varidt,start,count,tnat2)
1358#else
1359         status=NF_GET_VARA_REAL(ncidt,varidt,start,count,tnat2)
1360#endif
1361         IF (invert_y) THEN
1362           CALL invert_lat(iip1,jjp1,nlevnc,tnat2)
1363         ENDIF
1364     endif
1365
1366!  Humidite
1367     if (guide_Q) then
1368#ifdef NC_DOUBLE
1369         status=NF_GET_VARA_DOUBLE(ncidQ,varidQ,start,count,qnat2)
1370#else
1371         status=NF_GET_VARA_REAL(ncidQ,varidQ,start,count,qnat2)
1372#endif
1373         IF (invert_y) THEN
1374           CALL invert_lat(iip1,jjp1,nlevnc,qnat2)
1375         ENDIF
1376
1377     endif
1378
1379!  Vent meridien
1380     if (guide_v) then
1381         count(2)=jjm
1382#ifdef NC_DOUBLE
1383         status=NF_GET_VARA_DOUBLE(ncidv,varidv,start,count,vnat2)
1384#else
1385         status=NF_GET_VARA_REAL(ncidv,varidv,start,count,vnat2)
1386#endif
1387         IF (invert_y) THEN
1388           CALL invert_lat(iip1,jjm,nlevnc,vnat2)
1389         ENDIF
1390     endif
1391
1392!  Pression de surface
1393     if ((guide_P).OR.(guide_plevs.EQ.1))  then
1394         start(3)=timestep
1395         start(4)=0
1396         count(2)=jjp1
1397         count(3)=1
1398         count(4)=0
1399#ifdef NC_DOUBLE
1400         status=NF_GET_VARA_DOUBLE(ncidps,varidps,start,count,psnat2)
1401#else
1402         status=NF_GET_VARA_REAL(ncidps,varidps,start,count,psnat2)
1403#endif
1404         IF (invert_y) THEN
1405           CALL invert_lat(iip1,jjp1,1,psnat2)
1406         ENDIF
1407     endif
1408
1409  END SUBROUTINE guide_read
1410
1411!=======================================================================
1412  SUBROUTINE guide_read2D(timestep)
1413
1414    IMPLICIT NONE
1415
1416#include "netcdf.inc"
1417#include "dimensions.h"
1418#include "paramet.h"
1419
1420    INTEGER, INTENT(IN)   :: timestep
1421
1422    LOGICAL, SAVE         :: first=.TRUE.
1423! Identification fichiers et variables NetCDF:
1424    INTEGER, SAVE         :: ncidu,varidu,ncidv,varidv,ncidp,varidp
1425    INTEGER, SAVE         :: ncidQ,varidQ,ncidt,varidt,ncidps,varidps
1426    INTEGER               :: ncidpl,varidpl,varidap,varidbp
1427! Variables auxiliaires NetCDF:
1428    INTEGER, DIMENSION(4) :: start,count
1429    INTEGER               :: status,rcode
1430! Variables for 3D extension:
1431    REAL, DIMENSION (jjp1,llm) :: zu
1432    REAL, DIMENSION (jjm,llm)  :: zv
1433    INTEGER               :: i
1434
1435! -----------------------------------------------------------------
1436! Premier appel: initialisation de la lecture des fichiers
1437! -----------------------------------------------------------------
1438    if (first) then
1439         ncidpl=-99
1440         print*,'Guide: ouverture des fichiers guidage '
1441! Ap et Bp si niveaux de pression hybrides
1442         if (guide_plevs.EQ.1) then
1443             print *,'Lecture du guidage sur niveaux mod�le'
1444             rcode = nf90_open('apbp.nc', nf90_nowrite, ncidpl)
1445             rcode = nf90_inq_varid(ncidpl, 'AP', varidap)
1446             rcode = nf90_inq_varid(ncidpl, 'BP', varidbp)
1447             print*,'ncidpl,varidap',ncidpl,varidap
1448         endif
1449! Pression
1450         if (guide_plevs.EQ.2) then
1451             rcode = nf90_open('P.nc', nf90_nowrite, ncidp)
1452             rcode = nf90_inq_varid(ncidp, 'PRES', varidp)
1453             print*,'ncidp,varidp',ncidp,varidp
1454             if (ncidpl.eq.-99) ncidpl=ncidp
1455         endif
1456! Vent zonal
1457         if (guide_u) then
1458             rcode = nf90_open('u.nc', nf90_nowrite, ncidu)
1459             rcode = nf90_inq_varid(ncidu, 'UWND', varidu)
1460             print*,'ncidu,varidu',ncidu,varidu
1461             if (ncidpl.eq.-99) ncidpl=ncidu
1462         endif
1463! Vent meridien
1464         if (guide_v) then
1465             rcode = nf90_open('v.nc', nf90_nowrite, ncidv)
1466             rcode = nf90_inq_varid(ncidv, 'VWND', varidv)
1467             print*,'ncidv,varidv',ncidv,varidv
1468             if (ncidpl.eq.-99) ncidpl=ncidv
1469         endif
1470! Temperature
1471         if (guide_T) then
1472             rcode = nf90_open('T.nc', nf90_nowrite, ncidt)
1473             rcode = nf90_inq_varid(ncidt, 'AIR', varidt)
1474             print*,'ncidT,varidT',ncidt,varidt
1475             if (ncidpl.eq.-99) ncidpl=ncidt
1476         endif
1477! Humidite
1478         if (guide_Q) then
1479             rcode = nf90_open('hur.nc', nf90_nowrite, ncidQ)
1480             rcode = nf90_inq_varid(ncidQ, 'RH', varidQ)
1481             print*,'ncidQ,varidQ',ncidQ,varidQ
1482             if (ncidpl.eq.-99) ncidpl=ncidQ
1483         endif
1484! Pression de surface
1485         if ((guide_P).OR.(guide_plevs.EQ.1)) then
1486             rcode = nf90_open('ps.nc', nf90_nowrite, ncidps)
1487             rcode = nf90_inq_varid(ncidps, 'SP', varidps)
1488             print*,'ncidps,varidps',ncidps,varidps
1489         endif
1490! Coordonnee verticale
1491         if (guide_plevs.EQ.0) then
1492              rcode = nf90_inq_varid(ncidpl, 'LEVEL', varidpl)
1493              IF (rcode.NE.0) rcode = nf90_inq_varid(ncidpl, 'PRESSURE', varidpl)
1494              print*,'ncidpl,varidpl',ncidpl,varidpl
1495         endif
1496! Coefs ap, bp pour calcul de la pression aux differents niveaux
1497         if (guide_plevs.EQ.1) then
1498#ifdef NC_DOUBLE
1499             status=NF_GET_VARA_DOUBLE(ncidpl,varidap,1,nlevnc,apnc)
1500             status=NF_GET_VARA_DOUBLE(ncidpl,varidbp,1,nlevnc,bpnc)
1501#else
1502             status=NF_GET_VARA_REAL(ncidpl,varidap,1,nlevnc,apnc)
1503             status=NF_GET_VARA_REAL(ncidpl,varidbp,1,nlevnc,bpnc)
1504#endif
1505         elseif (guide_plevs.EQ.0) THEN
1506#ifdef NC_DOUBLE
1507             status=NF_GET_VARA_DOUBLE(ncidpl,varidpl,1,nlevnc,apnc)
1508#else
1509             status=NF_GET_VARA_REAL(ncidpl,varidpl,1,nlevnc,apnc)
1510#endif
1511             apnc=apnc*100.! conversion en Pascals
1512             bpnc(:)=0.
1513         endif
1514         first=.FALSE.
1515     endif ! (first)
1516
1517! -----------------------------------------------------------------
1518!   lecture des champs u, v, T, Q, ps
1519! -----------------------------------------------------------------
1520
1521!  dimensions pour les champs scalaires et le vent zonal
1522     start(1)=1
1523     start(2)=1
1524     start(3)=1
1525     start(4)=timestep
1526
1527     count(1)=1
1528     count(2)=jjp1
1529     count(3)=nlevnc
1530     count(4)=1
1531
1532!  Pression
1533     if (guide_plevs.EQ.2) then
1534#ifdef NC_DOUBLE
1535         status=NF_GET_VARA_DOUBLE(ncidp,varidp,start,count,zu)
1536#else
1537         status=NF_GET_VARA_REAL(ncidp,varidp,start,count,zu)
1538#endif
1539         DO i=1,iip1
1540             pnat2(i,:,:)=zu(:,:)
1541         ENDDO
1542
1543         IF (invert_y) THEN
1544           CALL invert_lat(iip1,jjp1,nlevnc,pnat2)
1545         ENDIF
1546     endif
1547!  Vent zonal
1548     if (guide_u) then
1549#ifdef NC_DOUBLE
1550         status=NF_GET_VARA_DOUBLE(ncidu,varidu,start,count,zu)
1551#else
1552         status=NF_GET_VARA_REAL(ncidu,varidu,start,count,zu)
1553#endif
1554         DO i=1,iip1
1555             unat2(i,:,:)=zu(:,:)
1556         ENDDO
1557
1558         IF (invert_y) THEN
1559           CALL invert_lat(iip1,jjp1,nlevnc,unat2)
1560         ENDIF
1561     endif
1562
1563!  Temperature
1564     if (guide_T) then
1565#ifdef NC_DOUBLE
1566         status=NF_GET_VARA_DOUBLE(ncidt,varidt,start,count,zu)
1567#else
1568         status=NF_GET_VARA_REAL(ncidt,varidt,start,count,zu)
1569#endif
1570         DO i=1,iip1
1571             tnat2(i,:,:)=zu(:,:)
1572         ENDDO
1573
1574         IF (invert_y) THEN
1575           CALL invert_lat(iip1,jjp1,nlevnc,tnat2)
1576         ENDIF
1577     endif
1578
1579!  Humidite
1580     if (guide_Q) then
1581#ifdef NC_DOUBLE
1582         status=NF_GET_VARA_DOUBLE(ncidQ,varidQ,start,count,zu)
1583#else
1584         status=NF_GET_VARA_REAL(ncidQ,varidQ,start,count,zu)
1585#endif
1586         DO i=1,iip1
1587             qnat2(i,:,:)=zu(:,:)
1588         ENDDO
1589         
1590         IF (invert_y) THEN
1591           CALL invert_lat(iip1,jjp1,nlevnc,qnat2)
1592         ENDIF
1593     endif
1594
1595!  Vent meridien
1596     if (guide_v) then
1597         count(2)=jjm
1598#ifdef NC_DOUBLE
1599         status=NF_GET_VARA_DOUBLE(ncidv,varidv,start,count,zv)
1600#else
1601         status=NF_GET_VARA_REAL(ncidv,varidv,start,count,zv)
1602#endif
1603         DO i=1,iip1
1604             vnat2(i,:,:)=zv(:,:)
1605         ENDDO
1606
1607         IF (invert_y) THEN
1608           CALL invert_lat(iip1,jjm,nlevnc,vnat2)
1609         ENDIF
1610     endif
1611
1612!  Pression de surface
1613     if ((guide_P).OR.(guide_plevs.EQ.1))  then
1614         start(3)=timestep
1615         start(4)=0
1616         count(2)=jjp1
1617         count(3)=1
1618         count(4)=0
1619#ifdef NC_DOUBLE
1620         status=NF_GET_VARA_DOUBLE(ncidps,varidps,start,count,zu(:,1))
1621#else
1622         status=NF_GET_VARA_REAL(ncidps,varidps,start,count,zu(:,1))
1623#endif
1624         DO i=1,iip1
1625             psnat2(i,:)=zu(:,1)
1626         ENDDO
1627
1628         IF (invert_y) THEN
1629           CALL invert_lat(iip1,jjp1,1,psnat2)
1630         ENDIF
1631     endif
1632
1633  END SUBROUTINE guide_read2D
1634 
1635!=======================================================================
1636  SUBROUTINE guide_out(varname,hsize,vsize,field,factt)
1637    USE parallel
1638    IMPLICIT NONE
1639
1640    INCLUDE "dimensions.h"
1641    INCLUDE "paramet.h"
1642    INCLUDE "netcdf.inc"
1643    INCLUDE "comgeom2.h"
1644    INCLUDE "comconst.h"
1645    INCLUDE "comvert.h"
1646   
1647    ! Variables entree
1648    CHARACTER, INTENT(IN)                          :: varname
1649    INTEGER,   INTENT (IN)                         :: hsize,vsize
1650    REAL, DIMENSION (iip1,hsize,vsize), INTENT(IN) :: field
1651    REAL, INTENT (IN)                              :: factt
1652
1653    ! Variables locales
1654    INTEGER, SAVE :: timestep=0
1655    ! Identites fichier netcdf
1656    INTEGER       :: nid, id_lonu, id_lonv, id_latu, id_latv, id_tim, id_lev
1657    INTEGER       :: vid_lonu,vid_lonv,vid_latu,vid_latv,vid_cu,vid_cv,vid_lev
1658    INTEGER, DIMENSION (3) :: dim3
1659    INTEGER, DIMENSION (4) :: dim4,count,start
1660    INTEGER                :: ierr, varid
1661   
1662    CALL gather_field(field,iip1*hsize,vsize,0)
1663   
1664    IF (mpi_rank /= 0) RETURN
1665   
1666    print *,'Guide: output timestep',timestep,'var ',varname
1667    IF (timestep.EQ.0) THEN
1668! ----------------------------------------------
1669! initialisation fichier de sortie
1670! ----------------------------------------------
1671! Ouverture du fichier
1672        ierr=NF_CREATE("guide_ins.nc",NF_CLOBBER,nid)
1673! Definition des dimensions
1674        ierr=NF_DEF_DIM(nid,"LONU",iip1,id_lonu)
1675        ierr=NF_DEF_DIM(nid,"LONV",iip1,id_lonv)
1676        ierr=NF_DEF_DIM(nid,"LATU",jjp1,id_latu)
1677        ierr=NF_DEF_DIM(nid,"LATV",jjm,id_latv)
1678        ierr=NF_DEF_DIM(nid,"LEVEL",llm,id_lev)
1679        ierr=NF_DEF_DIM(nid,"TIME",NF_UNLIMITED,id_tim)
1680
1681! Creation des variables dimensions
1682        ierr=NF_DEF_VAR(nid,"LONU",NF_FLOAT,1,id_lonu,vid_lonu)
1683        ierr=NF_DEF_VAR(nid,"LONV",NF_FLOAT,1,id_lonv,vid_lonv)
1684        ierr=NF_DEF_VAR(nid,"LATU",NF_FLOAT,1,id_latu,vid_latu)
1685        ierr=NF_DEF_VAR(nid,"LATV",NF_FLOAT,1,id_latv,vid_latv)
1686        ierr=NF_DEF_VAR(nid,"LEVEL",NF_FLOAT,1,id_lev,vid_lev)
1687        ierr=NF_DEF_VAR(nid,"cu",NF_FLOAT,2,(/id_lonu,id_latu/),vid_cu)
1688        ierr=NF_DEF_VAR(nid,"cv",NF_FLOAT,2,(/id_lonv,id_latv/),vid_cv)
1689       
1690        ierr=NF_ENDDEF(nid)
1691
1692! Enregistrement des variables dimensions
1693#ifdef NC_DOUBLE
1694        ierr = NF_PUT_VAR_DOUBLE(nid,vid_lonu,rlonu*180./pi)
1695        ierr = NF_PUT_VAR_DOUBLE(nid,vid_lonv,rlonv*180./pi)
1696        ierr = NF_PUT_VAR_DOUBLE(nid,vid_latu,rlatu*180./pi)
1697        ierr = NF_PUT_VAR_DOUBLE(nid,vid_latv,rlatv*180./pi)
1698        ierr = NF_PUT_VAR_DOUBLE(nid,vid_lev,presnivs)
1699        ierr = NF_PUT_VAR_DOUBLE(nid,vid_cu,cu)
1700        ierr = NF_PUT_VAR_DOUBLE(nid,vid_cv,cv)
1701#else
1702        ierr = NF_PUT_VAR_REAL(nid,vid_lonu,rlonu*180./pi)
1703        ierr = NF_PUT_VAR_REAL(nid,vid_lonv,rlonv*180./pi)
1704        ierr = NF_PUT_VAR_REAL(nid,vid_latu,rlatu*180./pi)
1705        ierr = NF_PUT_VAR_REAL(nid,vid_latv,rlatv*180./pi)
1706        ierr = NF_PUT_VAR_REAL(nid,vid_lev,presnivs)
1707        ierr = NF_PUT_VAR_REAL(nid,vid_cu,cu)
1708        ierr = NF_PUT_VAR_REAL(nid,vid_cv,cv)
1709#endif
1710! --------------------------------------------------------------------
1711! Cr�ation des variables sauvegard�es
1712! --------------------------------------------------------------------
1713        ierr = NF_REDEF(nid)
1714! Pressure (GCM)
1715        dim4=(/id_lonv,id_latu,id_lev,id_tim/)
1716        ierr = NF_DEF_VAR(nid,"P",NF_FLOAT,4,dim4,varid)
1717! Surface pressure (guidage)
1718        IF (guide_P) THEN
1719            dim3=(/id_lonv,id_latu,id_tim/)
1720            ierr = NF_DEF_VAR(nid,"ps",NF_FLOAT,3,dim3,varid)
1721        ENDIF
1722! Zonal wind
1723        IF (guide_u) THEN
1724            dim4=(/id_lonu,id_latu,id_lev,id_tim/)
1725            ierr = NF_DEF_VAR(nid,"ucov",NF_FLOAT,4,dim4,varid)
1726        ENDIF
1727! Merid. wind
1728        IF (guide_v) THEN
1729            dim4=(/id_lonv,id_latv,id_lev,id_tim/)
1730            ierr = NF_DEF_VAR(nid,"vcov",NF_FLOAT,4,dim4,varid)
1731        ENDIF
1732! Pot. Temperature
1733        IF (guide_T) THEN
1734            dim4=(/id_lonv,id_latu,id_lev,id_tim/)
1735            ierr = NF_DEF_VAR(nid,"teta",NF_FLOAT,4,dim4,varid)
1736        ENDIF
1737! Specific Humidity
1738        IF (guide_Q) THEN
1739            dim4=(/id_lonv,id_latu,id_lev,id_tim/)
1740            ierr = NF_DEF_VAR(nid,"q",NF_FLOAT,4,dim4,varid)
1741        ENDIF
1742       
1743        ierr = NF_ENDDEF(nid)
1744        ierr = NF_CLOSE(nid)
1745    ENDIF ! timestep=0
1746
1747! --------------------------------------------------------------------
1748! Enregistrement du champ
1749! --------------------------------------------------------------------
1750 
1751    ierr=NF_OPEN("guide_ins.nc",NF_WRITE,nid)
1752
1753    SELECT CASE (varname)
1754    CASE ("P")
1755        timestep=timestep+1
1756        ierr = NF_INQ_VARID(nid,"P",varid)
1757        start=(/1,1,1,timestep/)
1758        count=(/iip1,jjp1,llm,1/)
1759#ifdef NC_DOUBLE
1760        ierr = NF_PUT_VARA_DOUBLE(nid,varid,start,count,field)
1761#else
1762        ierr = NF_PUT_VARA_REAL(nid,varid,start,count,field)
1763#endif
1764    CASE ("SP")
1765        ierr = NF_INQ_VARID(nid,"ps",varid)
1766        start=(/1,1,timestep,0/)
1767        count=(/iip1,jjp1,1,0/)
1768#ifdef NC_DOUBLE
1769        ierr = NF_PUT_VARA_DOUBLE(nid,varid,start,count,field/factt)
1770#else
1771        ierr = NF_PUT_VARA_REAL(nid,varid,start,count,field/factt)
1772#endif
1773    CASE ("U")
1774        ierr = NF_INQ_VARID(nid,"ucov",varid)
1775        start=(/1,1,1,timestep/)
1776        count=(/iip1,jjp1,llm,1/)
1777#ifdef NC_DOUBLE
1778        ierr = NF_PUT_VARA_DOUBLE(nid,varid,start,count,field/factt)
1779#else
1780        ierr = NF_PUT_VARA_REAL(nid,varid,start,count,field/factt)
1781#endif
1782    CASE ("V")
1783        ierr = NF_INQ_VARID(nid,"vcov",varid)
1784        start=(/1,1,1,timestep/)
1785        count=(/iip1,jjm,llm,1/)
1786#ifdef NC_DOUBLE
1787        ierr = NF_PUT_VARA_DOUBLE(nid,varid,start,count,field/factt)
1788#else
1789        ierr = NF_PUT_VARA_REAL(nid,varid,start,count,field/factt)
1790#endif
1791    CASE ("T")
1792        ierr = NF_INQ_VARID(nid,"teta",varid)
1793        start=(/1,1,1,timestep/)
1794        count=(/iip1,jjp1,llm,1/)
1795#ifdef NC_DOUBLE
1796        ierr = NF_PUT_VARA_DOUBLE(nid,varid,start,count,field/factt)
1797#else
1798        ierr = NF_PUT_VARA_REAL(nid,varid,start,count,field/factt)
1799#endif
1800    CASE ("Q")
1801        ierr = NF_INQ_VARID(nid,"q",varid)
1802        start=(/1,1,1,timestep/)
1803        count=(/iip1,jjp1,llm,1/)
1804#ifdef NC_DOUBLE
1805        ierr = NF_PUT_VARA_DOUBLE(nid,varid,start,count,field/factt)
1806#else
1807        ierr = NF_PUT_VARA_REAL(nid,varid,start,count,field/factt)
1808#endif
1809    END SELECT
1810 
1811    ierr = NF_CLOSE(nid)
1812
1813  END SUBROUTINE guide_out
1814   
1815 
1816!===========================================================================
1817  subroutine correctbid(iim,nl,x)
1818    integer iim,nl
1819    real x(iim+1,nl)
1820    integer i,l
1821    real zz
1822
1823    do l=1,nl
1824        do i=2,iim-1
1825            if(abs(x(i,l)).gt.1.e10) then
1826               zz=0.5*(x(i-1,l)+x(i+1,l))
1827              print*,'correction ',i,l,x(i,l),zz
1828               x(i,l)=zz
1829            endif
1830         enddo
1831     enddo
1832     return
1833  end subroutine correctbid
1834
1835!===========================================================================
1836END MODULE guide_p_mod
Note: See TracBrowser for help on using the repository browser.