/[lmdze]/trunk/dyn3d/Guide/guide.f
ViewVC logotype

Diff of /trunk/dyn3d/Guide/guide.f

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 22 by guez, Fri Jul 31 15:18:47 2009 UTC revision 39 by guez, Tue Jan 25 15:11:05 2011 UTC
# Line 1  Line 1 
1  MODULE guide_m  MODULE guide_m
2    
3    ! From dyn3d/guide.F, v 1.3 2005/05/25 13:10:09    ! From dyn3d/guide.F, version 1.3 2005/05/25 13:10:09
4    ! and dyn3d/guide.h, v 1.1.1.1 2004/05/19 12:53:06    ! and dyn3d/guide.h, version 1.1.1.1 2004/05/19 12:53:06
5    
6    REAL :: tau_min_u, tau_max_u    IMPLICIT NONE
   REAL :: tau_min_v, tau_max_v  
   REAL :: tau_min_t, tau_max_t  
   REAL :: tau_min_q, tau_max_q  
   REAL :: tau_min_p, tau_max_p  
   REAL :: aire_min, aire_max  
7    
8      REAL tau_min_u, tau_max_u
9      REAL tau_min_v, tau_max_v
10      REAL tau_min_t, tau_max_t
11      REAL tau_min_q, tau_max_q
12      REAL tau_min_p, tau_max_p
13      REAL aire_min, aire_max
14    
   LOGICAL :: guide_u, guide_v, guide_t, guide_q, guide_p  
   REAL :: lat_min_guide, lat_max_guide  
15    
16    LOGICAL :: ncep, ini_anal    LOGICAL guide_u, guide_v, guide_t, guide_q, guide_p
17    INTEGER :: online    LOGICAL ncep, ini_anal
18      INTEGER online
19    
20  CONTAINS  CONTAINS
21    
22  SUBROUTINE guide(itau, ucov, vcov, teta, q, masse, ps)    SUBROUTINE guide(itau, ucov, vcov, teta, q, masse, ps)
23    
24    USE dimens_m, ONLY : jjm, llm      ! Author: F.Hourdin
   USE paramet_m, ONLY : iip1, ip1jm, ip1jmp1, jjp1, llmp1  
   USE comconst, ONLY : cpp, daysec, dtvr, kappa, pi  
   USE comvert, ONLY : ap, bp, preff, presnivs  
   USE conf_gcm_m, ONLY : day_step, iperiod  
   USE comgeom, ONLY : aire, rlatu, rlonv  
   USE serre, ONLY : clat, clon  
   USE q_sat_m, ONLY : q_sat  
   USE exner_hyb_m, ONLY : exner_hyb  
   USE pression_m, ONLY : pression  
   USE inigrads_m, ONLY : inigrads  
   use netcdf, only: nf90_nowrite, nf90_open, nf90_close  
25    
26    IMPLICIT NONE      USE comconst, ONLY : cpp, daysec, dtvr, kappa
27    INCLUDE 'netcdf.inc'      USE comvert, ONLY : ap, bp, preff, presnivs
28        USE conf_gcm_m, ONLY : day_step, iperiod
29        USE comgeom, ONLY : aire, rlatu, rlonv
30        USE dimens_m, ONLY : jjm, llm
31        USE exner_hyb_m, ONLY : exner_hyb
32        USE inigrads_m, ONLY : inigrads
33        use netcdf, only: nf90_nowrite, nf90_open, nf90_close
34        use nr_util, only: pi
35        USE paramet_m, ONLY : iip1, ip1jm, ip1jmp1, jjp1, llmp1
36        USE q_sat_m, ONLY : q_sat
37        USE serre, ONLY : clat, clon
38        use tau2alpha_m, only: tau2alpha
39    
40        INCLUDE 'netcdf.inc'
41    
42        !   variables dynamiques
43        REAL vcov(ip1jm, llm), ucov(ip1jmp1, llm) ! vents covariants
44        REAL, intent(inout):: teta(ip1jmp1, llm) ! temperature potentielle
45        REAL q(ip1jmp1, llm) ! temperature potentielle
46        REAL ps(ip1jmp1) ! pression  au sol
47        REAL masse(ip1jmp1, llm) ! masse d'air
48    
49    !      ......   Version  du 10/01/98    ..........      !   common passe pour des sorties
50        REAL dxdys(iip1, jjp1), dxdyu(iip1, jjp1), dxdyv(iip1, jjm)
51        COMMON /comdxdy/dxdys, dxdyu, dxdyv
52    
53    !             avec  coordonnees  verticales hybrides      !   variables dynamiques pour les reanalyses.
54    !   avec nouveaux operat. dissipation * ( gradiv2, divgrad2, nxgraro2 )      REAL ucovrea1(ip1jmp1, llm), vcovrea1(ip1jm, llm) !vts cov reas
55        REAL tetarea1(ip1jmp1, llm) ! temp pot  reales
56        REAL qrea1(ip1jmp1, llm) ! temp pot  reales
57        REAL psrea1(ip1jmp1) ! ps
58        REAL ucovrea2(ip1jmp1, llm), vcovrea2(ip1jm, llm) !vts cov reas
59        REAL tetarea2(ip1jmp1, llm) ! temp pot  reales
60        REAL qrea2(ip1jmp1, llm) ! temp pot  reales
61        REAL masserea2(ip1jmp1, llm) ! masse
62        REAL psrea2(ip1jmp1) ! ps
63    
64        REAL alpha_q(ip1jmp1)
65        REAL alpha_t(ip1jmp1), alpha_p(ip1jmp1)
66        REAL alpha_u(ip1jmp1), alpha_v(ip1jm)
67        REAL dday_step, toto, reste, itau_test
68        INTEGER step_rea, count_no_rea
69    
70        INTEGER ilon, ilat
71        REAL factt, ztau(ip1jmp1)
72    
73        INTEGER, INTENT (IN) :: itau
74        INTEGER ij, l
75        INTEGER ncidpl, varidpl, nlev, status
76        INTEGER rcod, rid
77        REAL ditau, tau, a
78        SAVE nlev
79    
80        !  TEST SUR QSAT
81        REAL p(ip1jmp1, llmp1), pk(ip1jmp1, llm), pks(ip1jmp1)
82        REAL pkf(ip1jmp1, llm)
83        REAL pres(ip1jmp1, llm)
84    
85        REAL qsat(ip1jmp1, llm)
86        REAL unskap
87        REAL tnat(ip1jmp1, llm)
88    
89        LOGICAL:: first = .TRUE.
90    
91        SAVE ucovrea1, vcovrea1, tetarea1, psrea1, qrea1
92        SAVE ucovrea2, vcovrea2, tetarea2, masserea2, psrea2, qrea2
93    
94        SAVE alpha_t, alpha_q, alpha_u, alpha_v, alpha_p, itau_test
95        SAVE step_rea, count_no_rea
96    
97        CHARACTER (10) file
98        INTEGER igrads
99        REAL dtgrads
100        SAVE igrads, dtgrads
101        DATA igrads, dtgrads/2, 100./
102    
103        !-----------------------------------------------------------------------
104    
105        PRINT *, 'Call sequence information: guide'
106    
107        ! calcul de l'humidite saturante
108    
109        forall (l = 1: llm + 1) p(:, l) = ap(l) + bp(l) * ps
110        CALL massdair(p, masse)
111        PRINT *, 'OK1'
112        CALL exner_hyb(ps, p, pks, pk, pkf)
113        PRINT *, 'OK2'
114        tnat(:, :) = pk(:, :)*teta(:, :)/cpp
115        PRINT *, 'OK3'
116        unskap = 1./kappa
117        pres(:, :) = preff*(pk(:, :)/cpp)**unskap
118        PRINT *, 'OK4'
119        qsat = q_sat(tnat, pres)
120    
121        !   initialisations pour la lecture des reanalyses.
122        !    alpha determine la part des injections de donnees a chaque etape
123        !    alpha=1 signifie pas d'injection
124        !    alpha=0 signifie injection totale
125    
126        PRINT *, 'ONLINE=', online
127        IF (online==-1) THEN
128           RETURN
129        END IF
130    
131    !=======================================================================      IF (first) THEN
132    
133    !   Auteur:  F.Hourdin         PRINT *, 'initialisation du guide '
134    !   -------         CALL conf_guide
135           PRINT *, 'apres conf_guide'
136    !   Objet:  
137    !   ------         file = 'guide'
138           CALL inigrads(igrads, rlonv, 180./pi, -180., 180., rlatu, -90., 90., &
139    !   GCM LMD nouvelle grille              180./pi, presnivs, 1., dtgrads, file, 'dyn_zon ')
140    
141    !=======================================================================         PRINT *, &
142                '1: en-ligne, 0: hors-ligne (x=x_rea), -1: climat (x=x_gcm)'
143    ! Dans inigeom , nouveaux calculs pour les elongations  cu , cv  
144    ! et possibilite d'appeler une fonction f(y)  a derivee tangente         IF (online==-1) RETURN
145    ! hyperbolique a la  place de la fonction a derivee sinusoidale.                 IF (online==1) THEN
146    
147    !   ...  Possibilite de choisir le shema de Van-leer pour l'advection de            !  Constantes de temps de rappel en jour
148    !         q  , en faisant iadv = 10  dans   traceur  (29/04/97) .            !  0.1 c'est en gros 2h30.
149              !  1e10  est une constante infinie donc en gros pas de guidage
150    !-----------------------------------------------------------------------  
151    !   Declarations:            !   coordonnees du centre du zoom
152    !   -------------            CALL coordij(clon, clat, ilon, ilat)
153              !   aire de la maille au centre du zoom
154              aire_min = aire(ilon+(ilat-1)*iip1)
155    !   variables dynamiques            !   aire maximale de la maille
156    REAL :: vcov(ip1jm, llm), ucov(ip1jmp1, llm) ! vents covariants            aire_max = 0.
157    REAL :: teta(ip1jmp1, llm) ! temperature potentielle            DO ij = 1, ip1jmp1
158    REAL :: q(ip1jmp1, llm) ! temperature potentielle               aire_max = max(aire_max, aire(ij))
159    REAL :: ps(ip1jmp1) ! pression  au sol            END DO
160    REAL :: masse(ip1jmp1, llm) ! masse d'air            !  factt = pas de temps en fraction de jour
161              factt = dtvr*iperiod/daysec
   !   common passe pour des sorties  
   REAL :: dxdys(iip1, jjp1), dxdyu(iip1, jjp1), dxdyv(iip1, jjm)  
   COMMON /comdxdy/dxdys, dxdyu, dxdyv  
   
   !   variables dynamiques pour les reanalyses.  
   REAL :: ucovrea1(ip1jmp1, llm), vcovrea1(ip1jm, llm) !vts cov reas  
   REAL :: tetarea1(ip1jmp1, llm) ! temp pot  reales  
   REAL :: qrea1(ip1jmp1, llm) ! temp pot  reales  
   REAL :: psrea1(ip1jmp1) ! ps  
   REAL :: ucovrea2(ip1jmp1, llm), vcovrea2(ip1jm, llm) !vts cov reas  
   REAL :: tetarea2(ip1jmp1, llm) ! temp pot  reales  
   REAL :: qrea2(ip1jmp1, llm) ! temp pot  reales  
   REAL :: masserea2(ip1jmp1, llm) ! masse  
   REAL :: psrea2(ip1jmp1) ! ps  
   
   REAL :: alpha_q(ip1jmp1)  
   REAL :: alpha_t(ip1jmp1), alpha_p(ip1jmp1)  
   REAL :: alpha_u(ip1jmp1), alpha_v(ip1jm)  
   REAL :: dday_step, toto, reste, itau_test  
   INTEGER :: step_rea, count_no_rea  
   
   !IM 180305   real aire_min, aire_max  
   INTEGER :: ilon, ilat  
   REAL :: factt, ztau(ip1jmp1)  
   
   INTEGER, INTENT (IN) :: itau  
   INTEGER :: ij, l  
   INTEGER :: ncidpl, varidpl, nlev, status  
   INTEGER :: rcod, rid  
   REAL :: ditau, tau, a  
   SAVE nlev  
   
   !  TEST SUR QSAT  
   REAL :: p(ip1jmp1, llmp1), pk(ip1jmp1, llm), pks(ip1jmp1)  
   REAL :: pkf(ip1jmp1, llm)  
   REAL :: pres(ip1jmp1, llm)  
   
   REAL :: qsat(ip1jmp1, llm)  
   REAL :: unskap  
   REAL :: tnat(ip1jmp1, llm)  
   !cccccccccccccccc  
   
   
   LOGICAL :: first  
   SAVE first  
   DATA first/ .TRUE./  
   
   SAVE ucovrea1, vcovrea1, tetarea1, psrea1, qrea1  
   SAVE ucovrea2, vcovrea2, tetarea2, masserea2, psrea2, qrea2  
   
   SAVE alpha_t, alpha_q, alpha_u, alpha_v, alpha_p, itau_test  
   SAVE step_rea, count_no_rea  
   
   CHARACTER (10) :: file  
   INTEGER :: igrads  
   REAL :: dtgrads  
   SAVE igrads, dtgrads  
   DATA igrads, dtgrads/2, 100./  
   
   PRINT *, 'Call sequence information: guide'  
   
   !-----------------------------------------------------------------------  
   ! calcul de l'humidite saturante  
   !-----------------------------------------------------------------------  
   CALL pression(ip1jmp1, ap, bp, ps, p)  
   CALL massdair(p, masse)  
   PRINT *, 'OK1'  
   CALL exner_hyb(ps, p, pks, pk, pkf)  
   PRINT *, 'OK2'  
   tnat(:, :) = pk(:, :)*teta(:, :)/cpp  
   PRINT *, 'OK3'  
   unskap = 1./kappa  
   pres(:, :) = preff*(pk(:, :)/cpp)**unskap  
   PRINT *, 'OK4'  
   qsat = q_sat(tnat, pres)  
   
   !-----------------------------------------------------------------------  
   
   !-----------------------------------------------------------------------  
   !   initialisations pour la lecture des reanalyses.  
   !    alpha determine la part des injections de donnees a chaque etape  
   !    alpha=1 signifie pas d'injection  
   !    alpha=0 signifie injection totale  
   !-----------------------------------------------------------------------  
   
   PRINT *, 'ONLINE=', online  
   IF (online==-1) THEN  
      RETURN  
   END IF  
   
   IF (first) THEN  
   
      PRINT *, 'initialisation du guide '  
      CALL conf_guide  
      PRINT *, 'apres conf_guide'  
   
      file = 'guide'  
      CALL inigrads(igrads, rlonv, 180./pi, -180., 180., rlatu, -90., 90., &  
           180./pi, presnivs, 1., dtgrads, file, 'dyn_zon ')  
   
      PRINT *, &  
           '1: en-ligne, 0: hors-ligne (x=x_rea), -1: climat (x=x_gcm)'  
   
      IF (online==-1) RETURN  
      IF (online==1) THEN  
   
         !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc  
         !  Constantes de temps de rappel en jour  
         !  0.1 c'est en gros 2h30.  
         !  1e10  est une constante infinie donc en gros pas de guidage  
         !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc  
         !   coordonnees du centre du zoom  
         CALL coordij(clon, clat, ilon, ilat)  
         !   aire de la maille au centre du zoom  
         aire_min = aire(ilon+(ilat-1)*iip1)  
         !   aire maximale de la maille  
         aire_max = 0.  
         DO ij = 1, ip1jmp1  
            aire_max = max(aire_max, aire(ij))  
         END DO  
         !  factt = pas de temps en fraction de jour  
         factt = dtvr*iperiod/daysec  
   
         !     subroutine tau2alpha(type, im, jm, factt, taumin, taumax, alpha)  
         CALL tau2alpha(3, iip1, jjm, factt, tau_min_v, tau_max_v, alpha_v)  
         CALL tau2alpha(2, iip1, jjp1, factt, tau_min_u, tau_max_u, alpha_u)  
         CALL tau2alpha(1, iip1, jjp1, factt, tau_min_t, tau_max_t, alpha_t)  
         CALL tau2alpha(1, iip1, jjp1, factt, tau_min_p, tau_max_p, alpha_p)  
         CALL tau2alpha(1, iip1, jjp1, factt, tau_min_q, tau_max_q, alpha_q)  
   
         CALL dump2d(iip1, jjp1, aire, 'AIRE MAILLe ')  
         CALL dump2d(iip1, jjp1, alpha_u, 'COEFF U   ')  
         CALL dump2d(iip1, jjp1, alpha_t, 'COEFF T   ')  
   
         !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc  
         !   Cas ou on force exactement par les variables analysees  
      ELSE  
         alpha_t = 0.  
         alpha_u = 0.  
         alpha_v = 0.  
         alpha_p = 0.  
         !           physic=.false.  
      END IF  
   
      itau_test = 1001  
      step_rea = 1  
      count_no_rea = 0  
      ncidpl = -99  
   
      !    itau_test    montre si l'importation a deja ete faite au rang itau  
      ! lecture d'un fichier netcdf pour determiner le nombre de niveaux  
      if (guide_u) then  
         if (ncidpl.eq.-99) rcod=nf90_open('u.nc',Nf90_NOWRITe,ncidpl)  
      endif  
   
      if (guide_v) then  
         if (ncidpl.eq.-99) rcod=nf90_open('v.nc',nf90_nowrite,ncidpl)  
      endif  
   
      if (guide_T) then  
         if (ncidpl.eq.-99) rcod=nf90_open('T.nc',nf90_nowrite,ncidpl)  
      endif  
   
      if (guide_Q) then  
         if (ncidpl.eq.-99) rcod=nf90_open('hur.nc',nf90_nowrite, ncidpl)  
      endif  
   
      IF (ncep) THEN  
         status = nf_inq_dimid(ncidpl, 'LEVEL', rid)  
      ELSE  
         status = nf_inq_dimid(ncidpl, 'PRESSURE', rid)  
      END IF  
      status = nf_inq_dimlen(ncidpl, rid, nlev)  
      PRINT *, 'nlev', nlev  
      rcod = nf90_close(ncidpl)  
      !   Lecture du premier etat des reanalyses.  
      CALL read_reanalyse(1, ps, ucovrea2, vcovrea2, tetarea2, qrea2, &  
           masserea2, psrea2, 1, nlev)  
      qrea2(:, :) = max(qrea2(:, :), 0.1)  
   
   
      !-----------------------------------------------------------------------  
      !   Debut de l'integration temporelle:  
      !   ----------------------------------  
   
   END IF ! first  
   
   !-----------------------------------------------------------------------  
   !----- IMPORTATION DES VENTS, PRESSION ET TEMPERATURE REELS:  
   !-----------------------------------------------------------------------  
   
   ditau = real(itau)  
   dday_step = real(day_step)  
   WRITE (*, *) 'ditau, dday_step'  
   WRITE (*, *) ditau, dday_step  
   toto = 4*ditau/dday_step  
   reste = toto - aint(toto)  
   !     write(*, *)'toto, reste', toto, reste  
   
   IF (reste==0.) THEN  
      IF (itau_test==itau) THEN  
         WRITE (*, *) 'deuxieme passage de advreel a itau=', itau  
         STOP  
      ELSE  
         vcovrea1(:, :) = vcovrea2(:, :)  
         ucovrea1(:, :) = ucovrea2(:, :)  
         tetarea1(:, :) = tetarea2(:, :)  
         qrea1(:, :) = qrea2(:, :)  
   
         PRINT *, 'LECTURE REANALYSES, pas ', step_rea, 'apres ', &  
              count_no_rea, ' non lectures'  
         step_rea = step_rea + 1  
         itau_test = itau  
         CALL read_reanalyse(step_rea, ps, ucovrea2, vcovrea2, tetarea2, &  
              qrea2, masserea2, psrea2, 1, nlev)  
         qrea2(:, :) = max(qrea2(:, :), 0.1)  
         factt = dtvr*iperiod/daysec  
         ztau(:) = factt/max(alpha_t(:), 1.E-10)  
         CALL wrgrads(igrads, 1, aire, 'aire      ', 'aire      ')  
         CALL wrgrads(igrads, 1, dxdys, 'dxdy      ', 'dxdy      ')  
         CALL wrgrads(igrads, 1, alpha_u, 'au        ', 'au        ')  
         CALL wrgrads(igrads, 1, alpha_t, 'at        ', 'at        ')  
         CALL wrgrads(igrads, 1, ztau, 'taut      ', 'taut      ')  
         CALL wrgrads(igrads, llm, ucov, 'u         ', 'u         ')  
         CALL wrgrads(igrads, llm, ucovrea2, 'ua        ', 'ua        ')  
         CALL wrgrads(igrads, llm, teta, 'T         ', 'T         ')  
         CALL wrgrads(igrads, llm, tetarea2, 'Ta        ', 'Ta        ')  
         CALL wrgrads(igrads, llm, qrea2, 'Qa        ', 'Qa        ')  
         CALL wrgrads(igrads, llm, q, 'Q         ', 'Q         ')  
   
         CALL wrgrads(igrads, llm, qsat, 'QSAT      ', 'QSAT      ')  
   
      END IF  
   ELSE  
      count_no_rea = count_no_rea + 1  
   END IF  
   
   !-----------------------------------------------------------------------  
   !   Guidage  
   !    x_gcm = a * x_gcm + (1-a) * x_reanalyses  
   !-----------------------------------------------------------------------  
   
   IF (ini_anal) PRINT *, 'ATTENTION !!! ON PART DU GUIDAGE'  
   
   ditau = real(itau)  
   dday_step = real(day_step)  
   
   
   tau = 4*ditau/dday_step  
   tau = tau - aint(tau)  
   
   !  ucov  
   IF (guide_u) THEN  
      DO l = 1, llm  
         DO ij = 1, ip1jmp1  
            a = (1.-tau)*ucovrea1(ij, l) + tau*ucovrea2(ij, l)  
            ucov(ij, l) = (1.-alpha_u(ij))*ucov(ij, l) + alpha_u(ij)*a  
            IF (first .AND. ini_anal) ucov(ij, l) = a  
         END DO  
      END DO  
   END IF  
   
   !  teta  
   IF (guide_t) THEN  
      DO l = 1, llm  
         DO ij = 1, ip1jmp1  
            a = (1.-tau)*tetarea1(ij, l) + tau*tetarea2(ij, l)  
            teta(ij, l) = (1.-alpha_t(ij))*teta(ij, l) + alpha_t(ij)*a  
            IF (first .AND. ini_anal) teta(ij, l) = a  
         END DO  
      END DO  
   END IF  
   
   !  P  
   IF (guide_p) THEN  
      DO ij = 1, ip1jmp1  
         a = (1.-tau)*psrea1(ij) + tau*psrea2(ij)  
         ps(ij) = (1.-alpha_p(ij))*ps(ij) + alpha_p(ij)*a  
         IF (first .AND. ini_anal) ps(ij) = a  
      END DO  
      CALL pression(ip1jmp1, ap, bp, ps, p)  
      CALL massdair(p, masse)  
   END IF  
   
   
   !  q  
   IF (guide_q) THEN  
      DO l = 1, llm  
         DO ij = 1, ip1jmp1  
            a = (1.-tau)*qrea1(ij, l) + tau*qrea2(ij, l)  
            !   hum relative en % -> hum specif  
            a = qsat(ij, l)*a*0.01  
            q(ij, l) = (1.-alpha_q(ij))*q(ij, l) + alpha_q(ij)*a  
            IF (first .AND. ini_anal) q(ij, l) = a  
         END DO  
      END DO  
   END IF  
   
   ! vcov  
   IF (guide_v) THEN  
      DO l = 1, llm  
         DO ij = 1, ip1jm  
            a = (1.-tau)*vcovrea1(ij, l) + tau*vcovrea2(ij, l)  
            vcov(ij, l) = (1.-alpha_v(ij))*vcov(ij, l) + alpha_v(ij)*a  
            IF (first .AND. ini_anal) vcov(ij, l) = a  
         END DO  
         IF (first .AND. ini_anal) vcov(ij, l) = a  
      END DO  
   END IF  
   
   !     call dump2d(iip1, jjp1, tetarea1, 'TETA REA 1     ')  
   !     call dump2d(iip1, jjp1, tetarea2, 'TETA REA 2     ')  
   !     call dump2d(iip1, jjp1, teta, 'TETA           ')  
   
   first = .FALSE.  
   
   RETURN  
 END SUBROUTINE guide  
   
   !=======================================================================  
   SUBROUTINE tau2alpha(type, pim, pjm, factt, taumin, taumax, alpha)  
     !=======================================================================  
   
     USE dimens_m, ONLY : iim, jjm  
     USE paramet_m, ONLY : iip1, jjp1  
     USE comconst, ONLY : pi  
     USE comgeom, ONLY : cu_2d, cv_2d, rlatu, rlatv  
     USE serre, ONLY : clat, clon, grossismx, grossismy  
     IMPLICIT NONE  
   
     !   arguments :  
     INTEGER :: type  
     INTEGER :: pim, pjm  
     REAL :: factt, taumin, taumax  
     REAL :: dxdy_, alpha(pim, pjm)  
     REAL :: dxdy_min, dxdy_max  
   
     !  local :  
     REAL :: alphamin, alphamax, gamma, xi  
     SAVE gamma  
     INTEGER :: i, j, ilon, ilat  
   
     LOGICAL :: first  
     SAVE first  
     DATA first/ .TRUE./  
162    
163      REAL :: zdx(iip1, jjp1), zdy(iip1, jjp1)            CALL tau2alpha(3, iip1, jjm, factt, tau_min_v, tau_max_v, alpha_v)
164              CALL tau2alpha(2, iip1, jjp1, factt, tau_min_u, tau_max_u, alpha_u)
165              CALL tau2alpha(1, iip1, jjp1, factt, tau_min_t, tau_max_t, alpha_t)
166              CALL tau2alpha(1, iip1, jjp1, factt, tau_min_p, tau_max_p, alpha_p)
167              CALL tau2alpha(1, iip1, jjp1, factt, tau_min_q, tau_max_q, alpha_q)
168    
169              CALL dump2d(iip1, jjp1, aire, 'AIRE MAILLe ')
170              CALL dump2d(iip1, jjp1, alpha_u, 'COEFF U   ')
171              CALL dump2d(iip1, jjp1, alpha_t, 'COEFF T   ')
172    
173      REAL :: zlat            !   Cas ou on force exactement par les variables analysees
174      REAL :: dxdys(iip1, jjp1), dxdyu(iip1, jjp1), dxdyv(iip1, jjm)         ELSE
175      COMMON /comdxdy/dxdys, dxdyu, dxdyv            alpha_t = 0.
176              alpha_u = 0.
177              alpha_v = 0.
178              alpha_p = 0.
179              !           physic=.false.
180           END IF
181    
182      IF (first) THEN         itau_test = 1001
183         DO j = 2, jjm         step_rea = 1
184            DO i = 2, iip1         count_no_rea = 0
185               zdx(i, j) = 0.5*(cu_2d(i-1, j)+cu_2d(i, j))/cos(rlatu(j))         ncidpl = -99
186            END DO  
187            zdx(1, j) = zdx(iip1, j)         !    itau_test    montre si l'importation a deja ete faite au rang itau
188         END DO         ! lecture d'un fichier netcdf pour determiner le nombre de niveaux
189         DO j = 2, jjm         if (guide_u) then
190            DO i = 1, iip1            if (ncidpl.eq.-99) rcod=nf90_open('u.nc',Nf90_NOWRITe,ncidpl)
191               zdy(i, j) = 0.5*(cv_2d(i, j-1)+cv_2d(i, j))         endif
192            END DO  
193         END DO         if (guide_v) then
194         DO i = 1, iip1            if (ncidpl.eq.-99) rcod=nf90_open('v.nc',nf90_nowrite,ncidpl)
195            zdx(i, 1) = zdx(i, 2)         endif
196            zdx(i, jjp1) = zdx(i, jjm)  
197            zdy(i, 1) = zdy(i, 2)         if (guide_T) then
198            zdy(i, jjp1) = zdy(i, jjm)            if (ncidpl.eq.-99) rcod=nf90_open('T.nc',nf90_nowrite,ncidpl)
199         END DO         endif
200         DO j = 1, jjp1  
201            DO i = 1, iip1         if (guide_Q) then
202               dxdys(i, j) = sqrt(zdx(i, j)*zdx(i, j)+zdy(i, j)*zdy(i, j))            if (ncidpl.eq.-99) rcod=nf90_open('hur.nc',nf90_nowrite, ncidpl)
203           endif
204    
205           IF (ncep) THEN
206              status = nf_inq_dimid(ncidpl, 'LEVEL', rid)
207           ELSE
208              status = nf_inq_dimid(ncidpl, 'PRESSURE', rid)
209           END IF
210           status = nf_inq_dimlen(ncidpl, rid, nlev)
211           PRINT *, 'nlev', nlev
212           rcod = nf90_close(ncidpl)
213           !   Lecture du premier etat des reanalyses.
214           CALL read_reanalyse(1, ps, ucovrea2, vcovrea2, tetarea2, qrea2, &
215                masserea2, psrea2, 1, nlev)
216           qrea2(:, :) = max(qrea2(:, :), 0.1)
217    
218    
219           !   Debut de l'integration temporelle:
220        END IF ! first
221    
222        ! IMPORTATION DES VENTS, PRESSION ET TEMPERATURE REELS:
223    
224        ditau = real(itau)
225        dday_step = real(day_step)
226        WRITE (*, *) 'ditau, dday_step'
227        WRITE (*, *) ditau, dday_step
228        toto = 4*ditau/dday_step
229        reste = toto - aint(toto)
230    
231        IF (reste==0.) THEN
232           IF (itau_test==itau) THEN
233              WRITE (*, *) 'deuxieme passage de advreel a itau=', itau
234              STOP
235           ELSE
236              vcovrea1(:, :) = vcovrea2(:, :)
237              ucovrea1(:, :) = ucovrea2(:, :)
238              tetarea1(:, :) = tetarea2(:, :)
239              qrea1(:, :) = qrea2(:, :)
240    
241              PRINT *, 'LECTURE REANALYSES, pas ', step_rea, 'apres ', &
242                   count_no_rea, ' non lectures'
243              step_rea = step_rea + 1
244              itau_test = itau
245              CALL read_reanalyse(step_rea, ps, ucovrea2, vcovrea2, tetarea2, &
246                   qrea2, masserea2, psrea2, 1, nlev)
247              qrea2(:, :) = max(qrea2(:, :), 0.1)
248              factt = dtvr*iperiod/daysec
249              ztau(:) = factt/max(alpha_t(:), 1.E-10)
250              CALL wrgrads(igrads, 1, aire, 'aire      ', 'aire      ')
251              CALL wrgrads(igrads, 1, dxdys, 'dxdy      ', 'dxdy      ')
252              CALL wrgrads(igrads, 1, alpha_u, 'au        ', 'au        ')
253              CALL wrgrads(igrads, 1, alpha_t, 'at        ', 'at        ')
254              CALL wrgrads(igrads, 1, ztau, 'taut      ', 'taut      ')
255              CALL wrgrads(igrads, llm, ucov, 'u         ', 'u         ')
256              CALL wrgrads(igrads, llm, ucovrea2, 'ua        ', 'ua        ')
257              CALL wrgrads(igrads, llm, teta, 'T         ', 'T         ')
258              CALL wrgrads(igrads, llm, tetarea2, 'Ta        ', 'Ta        ')
259              CALL wrgrads(igrads, llm, qrea2, 'Qa        ', 'Qa        ')
260              CALL wrgrads(igrads, llm, q, 'Q         ', 'Q         ')
261    
262              CALL wrgrads(igrads, llm, qsat, 'QSAT      ', 'QSAT      ')
263    
264           END IF
265        ELSE
266           count_no_rea = count_no_rea + 1
267        END IF
268    
269        !   Guidage
270        !    x_gcm = a * x_gcm + (1-a) * x_reanalyses
271    
272        IF (ini_anal) PRINT *, 'ATTENTION !!! ON PART DU GUIDAGE'
273    
274        ditau = real(itau)
275        dday_step = real(day_step)
276    
277    
278        tau = 4*ditau/dday_step
279        tau = tau - aint(tau)
280    
281        !  ucov
282        IF (guide_u) THEN
283           DO l = 1, llm
284              DO ij = 1, ip1jmp1
285                 a = (1.-tau)*ucovrea1(ij, l) + tau*ucovrea2(ij, l)
286                 ucov(ij, l) = (1.-alpha_u(ij))*ucov(ij, l) + alpha_u(ij)*a
287                 IF (first .AND. ini_anal) ucov(ij, l) = a
288            END DO            END DO
289         END DO         END DO
290         DO j = 1, jjp1      END IF
291            DO i = 1, iim  
292               dxdyu(i, j) = 0.5*(dxdys(i, j)+dxdys(i+1, j))      IF (guide_t) THEN
293           DO l = 1, llm
294              DO ij = 1, ip1jmp1
295                 a = (1.-tau)*tetarea1(ij, l) + tau*tetarea2(ij, l)
296                 teta(ij, l) = (1.-alpha_t(ij))*teta(ij, l) + alpha_t(ij)*a
297                 IF (first .AND. ini_anal) teta(ij, l) = a
298            END DO            END DO
           dxdyu(iip1, j) = dxdyu(1, j)  
299         END DO         END DO
300         DO j = 1, jjm      END IF
301            DO i = 1, iip1  
302               dxdyv(i, j) = 0.5*(dxdys(i, j)+dxdys(i+1, j))      !  P
303            END DO      IF (guide_p) THEN
304           DO ij = 1, ip1jmp1
305              a = (1.-tau)*psrea1(ij) + tau*psrea2(ij)
306              ps(ij) = (1.-alpha_p(ij))*ps(ij) + alpha_p(ij)*a
307              IF (first .AND. ini_anal) ps(ij) = a
308         END DO         END DO
309           forall (l = 1: llm + 1) p(:, l) = ap(l) + bp(l) * ps
310           CALL massdair(p, masse)
311        END IF
312    
313         CALL dump2d(iip1, jjp1, dxdys, 'DX2DY2 SCAL  ')  
314         CALL dump2d(iip1, jjp1, dxdyu, 'DX2DY2 U     ')      !  q
315         CALL dump2d(iip1, jjp1, dxdyv, 'DX2DY2 v     ')      IF (guide_q) THEN
316           DO l = 1, llm
317         !   coordonnees du centre du zoom            DO ij = 1, ip1jmp1
318         CALL coordij(clon, clat, ilon, ilat)               a = (1.-tau)*qrea1(ij, l) + tau*qrea2(ij, l)
319         !   aire de la maille au centre du zoom               !   hum relative en % -> hum specif
320         dxdy_min = dxdys(ilon, ilat)               a = qsat(ij, l)*a*0.01
321         !   dxdy maximale de la maille               q(ij, l) = (1.-alpha_q(ij))*q(ij, l) + alpha_q(ij)*a
322         dxdy_max = 0.               IF (first .AND. ini_anal) q(ij, l) = a
        DO j = 1, jjp1  
           DO i = 1, iip1  
              dxdy_max = max(dxdy_max, dxdys(i, j))  
323            END DO            END DO
324         END DO         END DO
   
        IF (abs(grossismx-1.)<0.1 .OR. abs(grossismy-1.)<0.1) THEN  
           PRINT *, 'ATTENTION modele peu zoome'  
           PRINT *, 'ATTENTION on prend une constante de guidage cste'  
           gamma = 0.  
        ELSE  
           gamma = (dxdy_max-2.*dxdy_min)/(dxdy_max-dxdy_min)  
           PRINT *, 'gamma=', gamma  
           IF (gamma<1.E-5) THEN  
              PRINT *, 'gamma =', gamma, '<1e-5'  
              STOP  
           END IF  
           PRINT *, 'gamma=', gamma  
           gamma = log(0.5)/log(gamma)  
        END IF  
325      END IF      END IF
326    
327      alphamin = factt/taumax      ! vcov
328      alphamax = factt/taumin      IF (guide_v) THEN
329           DO l = 1, llm
330      DO j = 1, pjm            DO ij = 1, ip1jm
331         DO i = 1, pim               a = (1.-tau)*vcovrea1(ij, l) + tau*vcovrea2(ij, l)
332            IF (type==1) THEN               vcov(ij, l) = (1.-alpha_v(ij))*vcov(ij, l) + alpha_v(ij)*a
333               dxdy_ = dxdys(i, j)               IF (first .AND. ini_anal) vcov(ij, l) = a
334               zlat = rlatu(j)*180./pi            END DO
335            ELSE IF (type==2) THEN            IF (first .AND. ini_anal) vcov(ij, l) = a
              dxdy_ = dxdyu(i, j)  
              zlat = rlatu(j)*180./pi  
           ELSE IF (type==3) THEN  
              dxdy_ = dxdyv(i, j)  
              zlat = rlatv(j)*180./pi  
           END IF  
           IF (abs(grossismx-1.)<0.1 .OR. abs(grossismy-1.)<0.1) THEN  
              !  pour une grille reguliere, xi=xxx**0=1 -> alpha=alphamin  
              alpha(i, j) = alphamin  
           ELSE  
              xi = ((dxdy_max-dxdy_)/(dxdy_max-dxdy_min))**gamma  
              xi = min(xi, 1.)  
              IF (lat_min_guide<=zlat .AND. zlat<=lat_max_guide) THEN  
                 alpha(i, j) = xi*alphamin + (1.-xi)*alphamax  
              ELSE  
                 alpha(i, j) = 0.  
              END IF  
           END IF  
336         END DO         END DO
337      END DO      END IF
338    
339        first = .FALSE.
340    
341      RETURN    END SUBROUTINE guide
   END SUBROUTINE tau2alpha  
342    
343  END MODULE guide_m  END MODULE guide_m

Legend:
Removed from v.22  
changed lines
  Added in v.39

  ViewVC Help
Powered by ViewVC 1.1.21