source: LMDZ4/trunk/libf/dyn3dpar/guide_p.F @ 1046

Last change on this file since 1046 was 1046, checked in by lmdzadmin, 16 years ago

Modifs guidage pour utiliser des champs de guidage sur niveaux hybrides
Ajout cle logique ok_gradsfile (.false. par defaut) pour activer sorties grads du guidage
FC/IM

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 17.4 KB
RevLine 
[630]1!
2! $Header$
3!
4      subroutine guide_pp(itau,ucov,vcov,teta,q,masse,ps)
5      USE parallel
6
7      IMPLICIT NONE
8
9c      ......   Version  du 10/01/98    ..........
10
11c             avec  coordonnees  verticales hybrides
12c   avec nouveaux operat. dissipation * ( gradiv2,divgrad2,nxgraro2 )
13
14c=======================================================================
15c
16c   Auteur:  F.Hourdin
17c   -------
18c
19c   Objet:
20c   ------
21c
22c   GCM LMD nouvelle grille
23c
24c=======================================================================
25
26c   ...  Dans inigeom , nouveaux calculs pour les elongations  cu , cv
27c        et possibilite d'appeler une fonction f(y)  a derivee tangente
28c        hyperbolique a la  place de la fonction a derivee sinusoidale.         
29
30c   ...  Possibilite de choisir le shema de Van-leer pour l'advection de
31c         q  , en faisant iadv = 10  dans   traceur  (29/04/97) .
32c
33c-----------------------------------------------------------------------
34c   Declarations:
35c   -------------
36
37#include "dimensions.h"
38#include "paramet.h"
39#include "comconst.h"
40#include "comdissnew.h"
41#include "comvert.h"
42#include "comgeom.h"
43#include "logic.h"
44#include "temps.h"
45#include "control.h"
46#include "ener.h"
47#include "netcdf.inc"
48#include "description.h"
49#include "serre.h"
50#include "tracstoke.h"
51#include "guide.h"
52
53
54c   variables dynamiques
55      REAL vcov(ip1jm,llm),ucov(ip1jmp1,llm) ! vents covariants
56      REAL teta(ip1jmp1,llm)                 ! temperature potentielle
57      REAL q(ip1jmp1,llm)                 ! temperature potentielle
58      REAL ps(ip1jmp1)                       ! pression  au sol
59      REAL masse(ip1jmp1,llm)                ! masse d'air
60
61c   common passe pour des sorties
62      real dxdys(iip1,jjp1),dxdyu(iip1,jjp1),dxdyv(iip1,jjm)
63      common/comdxdy/dxdys,dxdyu,dxdyv
64
65c   variables dynamiques pour les reanalyses.
66      REAL ucovrea1(ip1jmp1,llm),vcovrea1(ip1jm,llm) !vts cov reas
67      REAL tetarea1(ip1jmp1,llm)             ! temp pot  reales
68      REAL qrea1(ip1jmp1,llm)             ! temp pot  reales
69      REAL masserea1(ip1jmp1,llm)             ! masse
70      REAL psrea1(ip1jmp1)             ! ps
71      REAL ucovrea2(ip1jmp1,llm),vcovrea2(ip1jm,llm) !vts cov reas
72      REAL tetarea2(ip1jmp1,llm)             ! temp pot  reales
73      REAL qrea2(ip1jmp1,llm)             ! temp pot  reales
74      REAL masserea2(ip1jmp1,llm)             ! masse
75      REAL psrea2(ip1jmp1)             ! ps
76      real latmin
77
78      real alpha_q(ip1jmp1)
79      real alpha_T(ip1jmp1),alpha_P(ip1jmp1)
80      real alpha_u(ip1jmp1),alpha_v(ip1jm)
[1046]81      real alpha_pcor(llm)
[630]82      real dday_step,toto,reste,itau_test
83      INTEGER step_rea,count_no_rea
84
[764]85c      real aire_min,aire_max
[630]86      integer ilon,ilat
87      real factt,ztau(ip1jmp1)
88
89      INTEGER itau,ij,l,i,j
[764]90      integer ncidpl,varidpl,nlev,status
[630]91      integer rcod,rid
92      real ditau,tau,a
93      save nlev
94
95c  TEST SUR QSAT
96      real p(ip1jmp1,llmp1),pk(ip1jmp1,llm),pks(ip1jmp1)
97      real pkf(ip1jmp1,llm)
98      real pres(ip1jmp1,llm)
99      REAL alpha(ip1jmp1,llm),beta(ip1jmp1,llm)
100
101      real qsat(ip1jmp1,llm)
102      real unskap
103      real tnat(ip1jmp1,llm)
104ccccccccccccccccc
105
106
107      LOGICAL first
108      save first
109      data first/.true./
110
111      save ucovrea1,vcovrea1,tetarea1,masserea1,psrea1,qrea1
112      save ucovrea2,vcovrea2,tetarea2,masserea2,psrea2,qrea2
113
114      save alpha_T,alpha_q,alpha_u,alpha_v,alpha_P,itau_test
[1046]115      save alpha_pcor
[630]116      save step_rea,count_no_rea
117
118      character*10 file
119      integer igrads
120      real dtgrads
121      save igrads,dtgrads
122      data igrads,dtgrads/2,100./
123      integer :: ijb,ije,jjn
124
125C-----------------------------------------------------------------------
126c calcul de l'humidite saturante
127C-----------------------------------------------------------------------
128      ijb=ij_begin
129      ije=ij_end
130      jjn=jj_nb
131     
132      CALL pression_p( ip1jmp1, ap, bp, ps, p )
133      call massdair_p(p,masse)
134      CALL exner_hyb_p(ip1jmp1,ps,p,alpha,beta,pks,pk,pkf)
135      tnat(ijb:ije,:)=pk(ijb:ije,:)*teta(ijb:ije,:)/cpp
136      unskap   = 1./ kappa
137      pres(ijb:ije,:)=preff*(pk(ijb:ije,:)/cpp)**unskap
138      call q_sat(iip1*jjn*llm,tnat(ijb:ije,:),pres(ijb:ije,:),
139     .            qsat(ijb:ije,:))
140
141C-----------------------------------------------------------------------
142
143c-----------------------------------------------------------------------
144c   initialisations pour la lecture des reanalyses.
145c    alpha determine la part des injections de donnees a chaque etape
146c    alpha=1 signifie pas d'injection
147c    alpha=0 signifie injection totale
148c-----------------------------------------------------------------------
149
150      if(online.eq.-1) then
151          return
152      endif
153
154      if (first) then
155
156         print*,'initialisation du guide '
157         call conf_guide
158         print*,'apres conf_guide'
159
160         file='guide'
161         
162         if (mpi_rank==0) then
[1046]163         if (ok_gradsfile) then
[630]164         call inigrads(igrads,iip1
165     s  ,rlonv,180./pi,-180.,180.,jjp1,rlatu,-90.,90.,180./pi
166     s  ,llm,presnivs,1.
167     s  ,dtgrads,file,'dyn_zon ')
[1046]168         endif !ok_gradsfile
[630]169         endif
170         
171         print*
172     s   ,'1: en-ligne, 0: hors-ligne (x=x_rea), -1: climat (x=x_gcm)'
173
174         if(online.eq.-1) return
175         if (online.eq.1) then
176
177cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
178c  Constantes de temps de rappel en jour
179c  0.1 c'est en gros 2h30.
180c  1e10  est une constante infinie donc en gros pas de guidage
181cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
182c   coordonnees du centre du zoom
183           call coordij(clon,clat,ilon,ilat)
184c   aire de la maille au centre du zoom
185           aire_min=aire(ilon+(ilat-1)*iip1)
186c   aire maximale de la maille
187           aire_max=0.
188           do ij=1,ip1jmp1
189              aire_max=max(aire_max,aire(ij))
190           enddo
191C  factt = pas de temps en fraction de jour
192           factt=dtvr*iperiod/daysec
193
194c     subroutine tau2alpha(type,im,jm,factt,taumin,taumax,alpha)
195           call tau2alpha(3,iip1,jjm ,factt,tau_min_v,tau_max_v,alpha_v)
196           call tau2alpha(2,iip1,jjp1,factt,tau_min_u,tau_max_u,alpha_u)
197           call tau2alpha(1,iip1,jjp1,factt,tau_min_T,tau_max_T,alpha_T)
198           call tau2alpha(1,iip1,jjp1,factt,tau_min_P,tau_max_P,alpha_P)
199           call tau2alpha(1,iip1,jjp1,factt,tau_min_q,tau_max_q,alpha_q)
200
201           call dump2d(iip1,jjp1,aire,'AIRE MAILLe ')
202           call dump2d(iip1,jjp1,alpha_u,'COEFF U   ')
203           call dump2d(iip1,jjp1,alpha_T,'COEFF T   ')
204
205cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
206c   Cas ou on force exactement par les variables analysees
207         else
208            alpha_T=0.
209            alpha_u=0.
210            alpha_v=0.
211            alpha_P=0.
212c           physic=.false.
213         endif
[1046]214c correction de rappel dans couche limite
215c F.Codron
216         if (guide_BL) then
217           alpha_pcor(:)=1.
218         else
219           do l=1,llm
220             alpha_pcor(l)=(1.+tanh((0.85-presnivs(l)/preff)/0.05))/2.
221           enddo
222         endif
[630]223         itau_test=1001
224         step_rea=1
225         count_no_rea=0
[764]226         ncidpl=-99
[630]227c    itau_test    montre si l'importation a deja ete faite au rang itau
228c lecture d'un fichier netcdf pour determiner le nombre de niveaux
[764]229         IF (mpi_rank==0) THEN
[1046]230         if (guide_modele) then
231           if (ncidpl.eq.-99) ncidpl=NCOPN('apbp.nc',NCNOWRIT,rcod)
232         else   
[764]233         if (guide_u) then
234           if (ncidpl.eq.-99) ncidpl=NCOPN('u.nc',NCNOWRIT,rcod)
235         endif
236c
237         if (guide_v) then
238           if (ncidpl.eq.-99) ncidpl=NCOPN('v.nc',NCNOWRIT,rcod)
239         endif
240c
241         if (guide_T) then
242           if (ncidpl.eq.-99) ncidpl=NCOPN('T.nc',NCNOWRIT,rcod)
243         endif
244c
245         if (guide_Q) then
246           if (ncidpl.eq.-99) ncidpl=NCOPN('hur.nc',NCNOWRIT,rcod)
247         endif
248c
[1046]249         endif
[630]250         if (ncep) then
[764]251          status=NF_INQ_DIMID(ncidpl,'LEVEL',rid)
[630]252         else
[764]253          status=NF_INQ_DIMID(ncidpl,'PRESSURE',rid)
[630]254         endif
[764]255          status=NF_INQ_DIMLEN(ncidpl,rid,nlev)
[1046]256         print *,'nlev guide', nlev
257         call ncclos(ncidpl,rcod)
[630]258c   Lecture du premier etat des reanalyses.
259         call Gather_Field(ps,ip1jmp1,1,0)
260
261         if (mpi_rank==0) then
262         
263         call read_reanalyse(1,ps
264     s   ,ucovrea2,vcovrea2,tetarea2,qrea2,masserea2,psrea2,1,nlev)
265         qrea2(:,:)=max(qrea2(:,:),0.1)
266         
267         endif
268         
269         call Broadcast_Field(ucovrea2,ip1jmp1,llm,0)
270         call Broadcast_Field(vcovrea2,ip1jm,llm,0)
271         call Broadcast_Field(tetarea2,ip1jmp1,llm,0)
272         call Broadcast_Field(qrea2,ip1jmp1,llm,0)
273         call Broadcast_Field(masserea2,ip1jmp1,llm,0)
274         call Broadcast_Field(psrea2,ip1jmp1,1,0)
275         
276
277
278c-----------------------------------------------------------------------
279c   Debut de l'integration temporelle:
280c   ----------------------------------
281
282      endif ! first
283c
284C-----------------------------------------------------------------------
285C----- IMPORTATION DES VENTS,PRESSION ET TEMPERATURE REELS:
286C-----------------------------------------------------------------------
287
288      ditau=real(itau)
289      DDAY_step=real(day_step)
290      write(*,*)'ditau,dday_step'
291      write(*,*)ditau,dday_step
292      toto=4*ditau/dday_step
293      reste=toto-aint(toto)
294c     write(*,*)'toto,reste',toto,reste
295
296      if (reste.eq.0.) then
297        if (itau_test.eq.itau) then
298          write(*,*)'deuxieme passage de advreel a itau=',itau
299          stop
300        else
301        vcovrea1(:,:)=vcovrea2(:,:)
302        ucovrea1(:,:)=ucovrea2(:,:)
303        tetarea1(:,:)=tetarea2(:,:)
304        qrea1(:,:)=qrea2(:,:)
305
306          print*,'LECTURE REANALYSES, pas ',step_rea
307     s         ,'apres ',count_no_rea,' non lectures'
308           step_rea=step_rea+1
309           itau_test=itau
310           
311       call Gather_Field(ps,ip1jmp1,1,0)
312
313       if (mpi_rank==0) then
314           call read_reanalyse(step_rea,ps
315     s     ,ucovrea2,vcovrea2,tetarea2,qrea2,masserea2,psrea2,1,nlev)
316         qrea2(:,:)=max(qrea2(:,:),0.1)
317       endif
318
319       call Broadcast_Field(ucovrea2,ip1jmp1,llm,0)
320       call Broadcast_Field(vcovrea2,ip1jm,llm,0)
321       call Broadcast_Field(tetarea2,ip1jmp1,llm,0)
322       call Broadcast_Field(qrea2,ip1jmp1,llm,0)
323       call Broadcast_Field(masserea2,ip1jmp1,llm,0)
324       call Broadcast_Field(psrea2,ip1jmp1,1,0)
325       
326       factt=dtvr*iperiod/daysec
327       ztau(:)=factt/max(alpha_T(:),1.e-10)
328     
329       if (mpi_rank==0) then
[1046]330        if (ok_gradsfile) then
[630]331         call wrgrads(igrads,1,aire   ,'aire      ','aire      ' )
332         call wrgrads(igrads,1,dxdys  ,'dxdy      ','dxdy      ' )
333         call wrgrads(igrads,1,alpha_u,'au        ','au        ' )
334         call wrgrads(igrads,1,alpha_T,'at        ','at        ' )
335         call wrgrads(igrads,1,ztau,'taut      ','taut      ' )
336         call wrgrads(igrads,llm,ucov,'u         ','u         ' )
337         call wrgrads(igrads,llm,ucovrea2,'ua        ','ua        ' )
338         call wrgrads(igrads,llm,teta,'T         ','T         ' )
339         call wrgrads(igrads,llm,tetarea2,'Ta        ','Ta        ' )
340         call wrgrads(igrads,llm,qrea2,'Qa        ','Qa        ' )
341         call wrgrads(igrads,llm,q,'Q         ','Q         ' )
342         call wrgrads(igrads,llm,qsat,'QSAT      ','QSAT      ' )
[1046]343       endif !(ok_gradsfile) then
[630]344      endif
345     
346        endif
347      else
348        count_no_rea=count_no_rea+1
349      endif
350 
351C-----------------------------------------------------------------------
352c   Guidage
353c    x_gcm = a * x_gcm + (1-a) * x_reanalyses
354C-----------------------------------------------------------------------
355
356       if(ini_anal) print*,'ATTENTION !!! ON PART DU GUIDAGE'
357
358      ditau=real(itau)
359      dday_step=real(day_step)
360
361
362      tau=4*ditau/dday_step
363      tau=tau-aint(tau)
364
365c  ucov
366      ijb=ij_begin
367      ije=ij_end
368     
369      if (guide_u) then
370         do l=1,llm
371            do ij=ijb,ije
372                a=(1.-tau)*ucovrea1(ij,l)+tau*ucovrea2(ij,l)
[1046]373                ucov(ij,l)=(1.-alpha_u(ij))*ucov(ij,l)+alpha_u(ij)
374     $                     *alpha_pcor(l)*a
[630]375                if (first.and.ini_anal) ucov(ij,l)=a
376            enddo
377         enddo
378      endif
379
380c  teta
381      if (guide_T) then
382         do l=1,llm
383            do ij=ijb,ije
384                a=(1.-tau)*tetarea1(ij,l)+tau*tetarea2(ij,l)
[1046]385                teta(ij,l)=(1.-alpha_T(ij))*teta(ij,l)+alpha_T(ij)
386     $                     *alpha_pcor(l)*a
[630]387                if (first.and.ini_anal) teta(ij,l)=a
388            enddo
389         enddo
390      endif
391
392c  P
393      if (guide_P) then
394         do ij=ijb,ije
395             a=(1.-tau)*psrea1(ij)+tau*psrea2(ij)
396             ps(ij)=(1.-alpha_P(ij))*ps(ij)+alpha_P(ij)*a
397             if (first.and.ini_anal) ps(ij)=a
398         enddo
399         CALL pression_p(ip1jmp1,ap,bp,ps,p)
400         CALL massdair_p(p,masse)
401      endif
402
403
404c  q
405      if (guide_Q) then
406         do l=1,llm
407            do ij=ijb,ije
408                a=(1.-tau)*qrea1(ij,l)+tau*qrea2(ij,l)
409c   hum relative en % -> hum specif
410                a=qsat(ij,l)*a*0.01
[1046]411                q(ij,l)=(1.-alpha_Q(ij))*q(ij,l)+alpha_Q(ij)
412     $                     *alpha_pcor(l)*a
[630]413                if (first.and.ini_anal) q(ij,l)=a
414            enddo
415         enddo
416      endif
417
418c vcov
419      if (pole_sud) ije=ij_end-iip1
420     
421      if (guide_v) then
422         do l=1,llm
423            do ij=ijb,ije
424                a=(1.-tau)*vcovrea1(ij,l)+tau*vcovrea2(ij,l)
[1046]425                vcov(ij,l)=(1.-alpha_v(ij))*vcov(ij,l)+alpha_v(ij)
426     $                     *alpha_pcor(l)*a
[630]427                if (first.and.ini_anal) vcov(ij,l)=a
428            enddo
429         enddo
430      endif
431
432c     call dump2d(iip1,jjp1,tetarea1,'TETA REA 1     ')
433c     call dump2d(iip1,jjp1,tetarea2,'TETA REA 2     ')
434c     call dump2d(iip1,jjp1,teta,'TETA           ')
435
436         first=.false.
437
438      return
439      end
440
441c=======================================================================
442      subroutine tau2alpha(type,pim,pjm,factt,taumin,taumax,alpha)
443c=======================================================================
444
445      implicit none
446
447#include "dimensions.h"
448#include "paramet.h"
449#include "comconst.h"
450#include "comgeom2.h"
451#include "guide.h"
452#include "serre.h"
453
454c   arguments :
455      integer type
456      integer pim,pjm
457      real factt,taumin,taumax,dxdymin,dxdymax
458      real dxdy_,alpha(pim,pjm)
459      real dxdy_min,dxdy_max
460
461c  local :
462      real alphamin,alphamax,gamma,xi
463      save gamma
464      integer i,j,ilon,ilat
465
466      logical first
467      save first
468      data first/.true./
469
470      real cus(iip1,jjp1),cvs(iip1,jjp1)
471      real cuv(iip1,jjm),cvu(iip1,jjp1)
472      real zdx(iip1,jjp1),zdy(iip1,jjp1)
473
474      real zlat
475      real dxdys(iip1,jjp1),dxdyu(iip1,jjp1),dxdyv(iip1,jjm)
476      common/comdxdy/dxdys,dxdyu,dxdyv
477
478      if (first) then
479         do j=2,jjm
480            do i=2,iip1
481               zdx(i,j)=0.5*(cu(i-1,j)+cu(i,j))/cos(rlatu(j))
482            enddo
483            zdx(1,j)=zdx(iip1,j)
484         enddo
485         do j=2,jjm
486            do i=1,iip1
487               zdy(i,j)=0.5*(cv(i,j-1)+cv(i,j))
488            enddo
489         enddo
490         do i=1,iip1
491            zdx(i,1)=zdx(i,2)
492            zdx(i,jjp1)=zdx(i,jjm)
493            zdy(i,1)=zdy(i,2)
494            zdy(i,jjp1)=zdy(i,jjm)
495         enddo
496         do j=1,jjp1
497            do i=1,iip1
498               dxdys(i,j)=sqrt(zdx(i,j)*zdx(i,j)+zdy(i,j)*zdy(i,j))
499            enddo
500         enddo
501         do j=1,jjp1
502            do i=1,iim
503               dxdyu(i,j)=0.5*(dxdys(i,j)+dxdys(i+1,j))
504            enddo
505            dxdyu(iip1,j)=dxdyu(1,j)
506         enddo
507         do j=1,jjm
508            do i=1,iip1
509               dxdyv(i,j)=0.5*(dxdys(i,j)+dxdys(i+1,j))
510            enddo
511         enddo
512
[1046]513c         call dump2d(iip1,jjp1,dxdys,'DX2DY2 SCAL  ')
514c         call dump2d(iip1,jjp1,dxdyu,'DX2DY2 U     ')
[630]515         call dump2d(iip1,jjp1,dxdyv,'DX2DY2 v     ')
516
517c   coordonnees du centre du zoom
518           call coordij(clon,clat,ilon,ilat)
519c   aire de la maille au centre du zoom
520           dxdy_min=dxdys(ilon,ilat)
521c   dxdy maximale de la maille
522           dxdy_max=0.
523           do j=1,jjp1
524              do i=1,iip1
525                 dxdy_max=max(dxdy_max,dxdys(i,j))
526              enddo
527           enddo
528
529         if (abs(grossismx-1.).lt.0.1.or.abs(grossismy-1.).lt.0.1) then
530             print*,'ATTENTION modele peu zoome'
531             print*,'ATTENTION on prend une constante de guidage cste'
532             gamma=0.
533         else
534            gamma=(dxdy_max-2.*dxdy_min)/(dxdy_max-dxdy_min)
535            print*,'gamma=',gamma
536            if (gamma.lt.1.e-5) then
537              print*,'gamma =',gamma,'<1e-5'
538              stop
539            endif
[1046]540            gamma=log(0.5)/log(gamma)
541            if (gamma4) then
542              gamma=min(gamma,4.)
543            endif
[630]544            print*,'gamma=',gamma
545         endif
546      endif
547
548      alphamin=factt/taumax
549      alphamax=factt/taumin
550
551      do j=1,pjm
552         do i=1,pim
553            if (type.eq.1) then
554               dxdy_=dxdys(i,j)
555               zlat=rlatu(j)*180./pi
556            elseif (type.eq.2) then
557               dxdy_=dxdyu(i,j)
558               zlat=rlatu(j)*180./pi
559            elseif (type.eq.3) then
560               dxdy_=dxdyv(i,j)
561               zlat=rlatv(j)*180./pi
562            endif
[764]563          if (abs(grossismx-1.).lt.0.1.or.abs(grossismy-1.).lt.0.1) then
564c  pour une grille reguliere, xi=xxx**0=1 -> alpha=alphamin
565             alpha(i,j)=alphamin
566          else
[630]567            xi=((dxdy_max-dxdy_)/(dxdy_max-dxdy_min))**gamma
568            xi=min(xi,1.)
569            if(lat_min_guide.le.zlat .and. zlat.le.lat_max_guide) then
570               alpha(i,j)=xi*alphamin+(1.-xi)*alphamax
571            else
572               alpha(i,j)=0.
573            endif
[764]574          endif
[630]575         enddo
576      enddo
577
578
579      return
580      end
Note: See TracBrowser for help on using the repository browser.