source: LMDZ6/trunk/libf/dyn3d/guide_mod.F90 @ 4248

Last change on this file since 4248 was 4246, checked in by evignon, 2 years ago

controle dans les .def du presnivs limite en dessous duquel on ne guide plus
si guide_BL=false
Etienne, pour valentin

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