/[lmdze]/trunk/Sources/dyn3d/bilan_dyn.f
ViewVC logotype

Diff of /trunk/Sources/dyn3d/bilan_dyn.f

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

trunk/libf/dyn3d/bilan_dyn.f revision 30 by guez, Thu Apr 1 09:07:28 2010 UTC trunk/libf/dyn3d/bilan_dyn.f90 revision 57 by guez, Mon Jan 30 12:54:02 2012 UTC
# Line 1  Line 1 
1  !  module bilan_dyn_m
 ! $Header: /home/cvsroot/LMDZ4/libf/dyn3d/bilan_dyn.F,v 1.5 2005/03/16 10:12:17 fairhead Exp $  
 !  
       SUBROUTINE bilan_dyn (ntrac,dt_app,dt_cum,  
      s  ps,masse,pk,flux_u,flux_v,teta,phi,ucov,vcov,trac)  
   
 c   AFAIRE  
 c   Prevoir en champ nq+1 le diagnostique de l'energie  
 c   en faisant Qzon=Cv T + L * ...  
 c             vQ..A=Cp T + L * ...  
   
       USE histcom  
       use calendar  
       use histwrite_m  
       use dimens_m  
       use paramet_m  
       use comconst  
       use comvert  
       use comgeom, only: constang_2d, cu_2d, cv_2d, rlatv  
       use temps  
       use iniprint  
       use inigrads_m, only: inigrads  
   
       IMPLICIT NONE  
   
   
 c====================================================================  
 c  
 c   Sous-programme consacre à des diagnostics dynamiques de base  
 c  
 c  
 c   De facon generale, les moyennes des scalaires Q sont ponderees par  
 c   la masse.  
 c  
 c   Les flux de masse sont eux simplement moyennes.  
 c  
 c====================================================================  
   
 c   Arguments :  
 c   ===========  
   
       integer ntrac  
       real dt_app,dt_cum  
       real ps(iip1,jjp1)  
       real masse(iip1,jjp1,llm),pk(iip1,jjp1,llm)  
       real flux_u(iip1,jjp1,llm)  
       real flux_v(iip1,jjm,llm)  
       real teta(iip1,jjp1,llm)  
       real phi(iip1,jjp1,llm)  
       real ucov(iip1,jjp1,llm)  
       real vcov(iip1,jjm,llm)  
       real trac(iip1,jjp1,llm,ntrac)  
   
 c   Local :  
 c   =======  
   
       integer icum,ncum  
       logical first  
       real zz,zqy,zfactv(jjm,llm)  
   
       integer nQ  
       parameter (nQ=7)  
   
   
 cym      character*6 nom(nQ)  
 cym      character*6 unites(nQ)  
       character*6,save :: nom(nQ)  
       character*6,save :: unites(nQ)  
   
       character*10 file  
       integer ifile  
       parameter (ifile=4)  
   
       integer itemp,igeop,iecin,iang,iu,iovap,iun  
       integer i_sortie  
   
       save first,icum,ncum  
       save itemp,igeop,iecin,iang,iu,iovap,iun  
       save i_sortie  
   
       real time  
       integer itau  
       save time,itau  
       data time,itau/0.,0/  
   
       data first/.true./  
       data itemp,igeop,iecin,iang,iu,iovap,iun/1,2,3,4,5,6,7/  
       data i_sortie/1/  
   
       real ww  
   
 c   variables dynamiques intermédiaires  
       REAL vcont(iip1,jjm,llm),ucont(iip1,jjp1,llm)  
       REAL ang(iip1,jjp1,llm),unat(iip1,jjp1,llm)  
       REAL massebx(iip1,jjp1,llm),masseby(iip1,jjm,llm)  
       REAL vorpot(iip1,jjm,llm)  
       REAL w(iip1,jjp1,llm),ecin(iip1,jjp1,llm),convm(iip1,jjp1,llm)  
       REAL bern(iip1,jjp1,llm)  
   
 c   champ contenant les scalaires advectés.  
       real Q(iip1,jjp1,llm,nQ)  
       
 c   champs cumulés  
       real ps_cum(iip1,jjp1)  
       real masse_cum(iip1,jjp1,llm)  
       real flux_u_cum(iip1,jjp1,llm)  
       real flux_v_cum(iip1,jjm,llm)  
       real Q_cum(iip1,jjp1,llm,nQ)  
       real flux_uQ_cum(iip1,jjp1,llm,nQ)  
       real flux_vQ_cum(iip1,jjm,llm,nQ)  
       real flux_wQ_cum(iip1,jjp1,llm,nQ)  
       real dQ(iip1,jjp1,llm,nQ)  
   
       save ps_cum,masse_cum,flux_u_cum,flux_v_cum  
       save Q_cum,flux_uQ_cum,flux_vQ_cum  
   
 c   champs de tansport en moyenne zonale  
       integer ntr,itr  
       parameter (ntr=5)  
   
 cym      character*10 znom(ntr,nQ)  
 cym      character*20 znoml(ntr,nQ)  
 cym      character*10 zunites(ntr,nQ)  
       character*10,save :: znom(ntr,nQ)  
       character*20,save :: znoml(ntr,nQ)  
       character*10,save :: zunites(ntr,nQ)  
   
       integer iave,itot,immc,itrs,istn  
       data iave,itot,immc,itrs,istn/1,2,3,4,5/  
       character*3 ctrs(ntr)  
       data ctrs/'  ','TOT','MMC','TRS','STN'/  
   
       real zvQ(jjm,llm,ntr,nQ),zvQtmp(jjm,llm)  
       real zavQ(jjm,ntr,nQ),psiQ(jjm,llm+1,nQ)  
       real zmasse(jjm,llm),zamasse(jjm)  
   
       real zv(jjm,llm),psi(jjm,llm+1)  
   
       integer i,j,l,iQ  
   
   
 c   Initialisation du fichier contenant les moyennes zonales.  
 c   ---------------------------------------------------------  
   
       integer fileid  
       integer thoriid, zvertiid  
       save fileid  
   
       integer ndex3d(jjm*llm)  
   
 C   Variables locales  
 C  
       real zjulian  
       character*3 str  
       character*10 ctrac  
       integer ii,jj  
       integer zan, dayref  
 C  
       real rlong(jjm),rlatg(jjm)  
   
       !!print *, "Call sequence information: bilan_dyn"  
   
 c=====================================================================  
 c   Initialisation  
 c=====================================================================  
   
       time=time+dt_app  
       itau=itau+1  
   
       if (first) then  
   
   
         icum=0  
 c       initialisation des fichiers  
         first=.false.  
 c   ncum est la frequence de stokage en pas de temps  
         ncum=dt_cum/dt_app  
         if (abs(ncum*dt_app-dt_cum).gt.1.e-5*dt_app) then  
            print *,  
      .            'Pb : le pas de cumule doit etre multiple du pas'  
            print *,'dt_app=',dt_app  
            print *,'dt_cum=',dt_cum  
            stop  
         endif  
   
         if (i_sortie.eq.1) then  
          file='dynzon'  
          call inigrads(ifile ,(/0./),180./pi,0.,0.,rlatv,-90.,90.,  
      $        180./pi ,presnivs,1. ,dt_cum,file,'dyn_zon ')  
         endif  
   
         nom(itemp)='T'  
         nom(igeop)='gz'  
         nom(iecin)='K'  
         nom(iang)='ang'  
         nom(iu)='u'  
         nom(iovap)='ovap'  
         nom(iun)='un'  
   
         unites(itemp)='K'  
         unites(igeop)='m2/s2'  
         unites(iecin)='m2/s2'  
         unites(iang)='ang'  
         unites(iu)='m/s'  
         unites(iovap)='kg/kg'  
         unites(iun)='un'  
   
   
 c   Initialisation du fichier contenant les moyennes zonales.  
 c   ---------------------------------------------------------  
   
       zan = annee_ref  
       dayref = day_ref  
       CALL ymds2ju(zan, 1, dayref, 0.0, zjulian)  
         
       rlong=0.  
       rlatg=rlatv*180./pi  
         
       call histbeg_totreg('dynzon', rlong(:1), rlatg,  
      .             1, 1, 1, jjm,  
      .             itau_dyn, zjulian, dt_cum, thoriid, fileid)  
   
 C  
 C  Appel a histvert pour la grille verticale  
 C  
       call histvert(fileid, 'presnivs', 'Niveaux sigma','mb',  
      .              llm, presnivs, zvertiid)  
 C  
 C  Appels a histdef pour la definition des variables a sauvegarder  
       do iQ=1,nQ  
          do itr=1,ntr  
             if(itr.eq.1) then  
                znom(itr,iQ)=nom(iQ)  
                znoml(itr,iQ)=nom(iQ)  
                zunites(itr,iQ)=unites(iQ)  
             else  
                znom(itr,iQ)=ctrs(itr)//'v'//nom(iQ)  
                znoml(itr,iQ)='transport : v * '//nom(iQ)//' '//ctrs(itr)  
                zunites(itr,iQ)='m/s * '//unites(iQ)  
             endif  
          enddo  
       enddo  
   
 c   Declarations des champs avec dimension verticale  
 c      print*,'1HISTDEF'  
       do iQ=1,nQ  
          do itr=1,ntr  
       IF (prt_level > 5)  
      . print *,'var ',itr,iQ  
      .      ,znom(itr,iQ),znoml(itr,iQ),zunites(itr,iQ)  
             call histdef(fileid,znom(itr,iQ),znoml(itr,iQ),  
      .        zunites(itr,iQ),1,jjm,thoriid,llm,1,llm,zvertiid,  
      .        'ave(X)',dt_cum,dt_cum)  
          enddo  
 c   Declarations pour les fonctions de courant  
 c      print*,'2HISTDEF'  
           call histdef(fileid,'psi'//nom(iQ)  
      .      ,'stream fn. '//znoml(itot,iQ),  
      .      zunites(itot,iQ),1,jjm,thoriid,llm,1,llm,zvertiid,  
      .      'ave(X)',dt_cum,dt_cum)  
       enddo  
   
   
 c   Declarations pour les champs de transport d'air  
 c      print*,'3HISTDEF'  
       call histdef(fileid, 'masse', 'masse',  
      .             'kg', 1, jjm, thoriid, llm, 1, llm, zvertiid,  
      .             'ave(X)', dt_cum, dt_cum)  
       call histdef(fileid, 'v', 'v',  
      .             'm/s', 1, jjm, thoriid, llm, 1, llm, zvertiid,  
      .             'ave(X)', dt_cum, dt_cum)  
 c   Declarations pour les fonctions de courant  
 c      print*,'4HISTDEF'  
           call histdef(fileid,'psi','stream fn. MMC ','mega t/s',  
      .      1,jjm,thoriid,llm,1,llm,zvertiid,  
      .      'ave(X)',dt_cum,dt_cum)  
   
   
 c   Declaration des champs 1D de transport en latitude  
 c      print*,'5HISTDEF'  
       do iQ=1,nQ  
          do itr=2,ntr  
             call histdef(fileid,'a'//znom(itr,iQ),znoml(itr,iQ),  
      .        zunites(itr,iQ),1,jjm,thoriid,1,1,1,-99,  
      .        'ave(X)',dt_cum,dt_cum)  
          enddo  
       enddo  
   
   
 c      print*,'8HISTDEF'  
                CALL histend(fileid)  
   
   
       endif  
   
   
 c=====================================================================  
 c   Calcul des champs dynamiques  
 c   ----------------------------  
   
 c   énergie cinétique  
       ucont(:,:,:)=0  
       CALL covcont(llm,ucov,vcov,ucont,vcont)  
       CALL enercin(vcov,ucov,vcont,ucont,ecin)  
   
 c   moment cinétique  
       do l=1,llm  
          ang(:,:,l)=ucov(:,:,l)+constang_2d(:,:)  
          unat(:,:,l)=ucont(:,:,l)*cu_2d(:,:)  
       enddo  
   
       Q(:,:,:,itemp)=teta(:,:,:)*pk(:,:,:)/cpp  
       Q(:,:,:,igeop)=phi(:,:,:)  
       Q(:,:,:,iecin)=ecin(:,:,:)  
       Q(:,:,:,iang)=ang(:,:,:)  
       Q(:,:,:,iu)=unat(:,:,:)  
       Q(:,:,:,iovap)=trac(:,:,:,1)  
       Q(:,:,:,iun)=1.  
   
   
 c=====================================================================  
 c   Cumul  
 c=====================================================================  
 c  
       if(icum.EQ.0) then  
          ps_cum=0.  
          masse_cum=0.  
          flux_u_cum=0.  
          flux_v_cum=0.  
          Q_cum=0.  
          flux_vQ_cum=0.  
          flux_uQ_cum=0.  
       endif  
   
       IF (prt_level > 5)  
      . print *,'dans bilan_dyn ',icum,'->',icum+1  
       icum=icum+1  
   
 c   accumulation des flux de masse horizontaux  
       ps_cum=ps_cum+ps  
       masse_cum=masse_cum+masse  
       flux_u_cum=flux_u_cum+flux_u  
       flux_v_cum=flux_v_cum+flux_v  
       do iQ=1,nQ  
       Q_cum(:,:,:,iQ)=Q_cum(:,:,:,iQ)+Q(:,:,:,iQ)*masse(:,:,:)  
       enddo  
   
 c=====================================================================  
 c  FLUX ET TENDANCES  
 c=====================================================================  
   
 c   Flux longitudinal  
 c   -----------------  
       do iQ=1,nQ  
          do l=1,llm  
             do j=1,jjp1  
                do i=1,iim  
                   flux_uQ_cum(i,j,l,iQ)=flux_uQ_cum(i,j,l,iQ)  
      s            +flux_u(i,j,l)*0.5*(Q(i,j,l,iQ)+Q(i+1,j,l,iQ))  
                enddo  
                flux_uQ_cum(iip1,j,l,iQ)=flux_uQ_cum(1,j,l,iQ)  
             enddo  
          enddo  
       enddo  
   
 c    flux méridien  
 c    -------------  
       do iQ=1,nQ  
          do l=1,llm  
             do j=1,jjm  
                do i=1,iip1  
                   flux_vQ_cum(i,j,l,iQ)=flux_vQ_cum(i,j,l,iQ)  
      s            +flux_v(i,j,l)*0.5*(Q(i,j,l,iQ)+Q(i,j+1,l,iQ))  
                enddo  
             enddo  
          enddo  
       enddo  
   
   
 c    tendances  
 c    ---------  
   
 c   convergence horizontale  
       call  convflu(flux_uQ_cum,flux_vQ_cum,llm*nQ,dQ)  
   
 c   calcul de la vitesse verticale  
       call convmas(flux_u_cum,flux_v_cum,convm)  
       CALL vitvert(convm,w)  
   
       do iQ=1,nQ  
          do l=1,llm-1  
             do j=1,jjp1  
                do i=1,iip1  
                   ww=-0.5*w(i,j,l+1)*(Q(i,j,l,iQ)+Q(i,j,l+1,iQ))  
                   dQ(i,j,l  ,iQ)=dQ(i,j,l  ,iQ)-ww  
                   dQ(i,j,l+1,iQ)=dQ(i,j,l+1,iQ)+ww  
                enddo  
             enddo  
          enddo  
       enddo  
       IF (prt_level > 5)  
      . print *,'Apres les calculs fait a chaque pas'  
 c=====================================================================  
 c   PAS DE TEMPS D'ECRITURE  
 c=====================================================================  
       if (icum.eq.ncum) then  
 c=====================================================================  
   
       IF (prt_level > 5)  
      . print *,'Pas d ecriture'  
   
 c   Normalisation  
       do iQ=1,nQ  
          Q_cum(:,:,:,iQ)=Q_cum(:,:,:,iQ)/masse_cum(:,:,:)  
       enddo  
       zz=1./float(ncum)  
       ps_cum=ps_cum*zz  
       masse_cum=masse_cum*zz  
       flux_u_cum=flux_u_cum*zz  
       flux_v_cum=flux_v_cum*zz  
       flux_uQ_cum=flux_uQ_cum*zz  
       flux_vQ_cum=flux_vQ_cum*zz  
       dQ=dQ*zz  
   
   
 c   A retravailler eventuellement  
 c   division de dQ par la masse pour revenir aux bonnes grandeurs  
       do iQ=1,nQ  
          dQ(:,:,:,iQ)=dQ(:,:,:,iQ)/masse_cum(:,:,:)  
       enddo  
   
 c=====================================================================  
 c   Transport méridien  
 c=====================================================================  
   
 c   cumul zonal des masses des mailles  
 c   ----------------------------------  
       zv=0.  
       zmasse=0.  
       call massbar(masse_cum,massebx,masseby)  
       do l=1,llm  
          do j=1,jjm  
             do i=1,iim  
                zmasse(j,l)=zmasse(j,l)+masseby(i,j,l)  
                zv(j,l)=zv(j,l)+flux_v_cum(i,j,l)  
             enddo  
             zfactv(j,l)=cv_2d(1,j)/zmasse(j,l)  
          enddo  
       enddo  
   
 c     print*,'3OK'  
 c   --------------------------------------------------------------  
 c   calcul de la moyenne zonale du transport :  
 c   ------------------------------------------  
 c  
 c                                     --  
 c TOT : la circulation totale       [ vq ]  
 c  
 c                                      -     -  
 c MMC : mean meridional circulation [ v ] [ q ]  
 c  
 c                                     ----      --       - -  
 c TRS : transitoires                [ v'q'] = [ vq ] - [ v q ]  
 c  
 c                                     - * - *       - -       -     -  
 c STT : stationaires                [ v   q   ] = [ v q ] - [ v ] [ q ]  
 c  
 c                                              - -  
 c    on utilise aussi l'intermediaire TMP :  [ v q ]  
 c  
 c    la variable zfactv transforme un transport meridien cumule  
 c    en kg/s * unte-du-champ-transporte en m/s * unite-du-champ-transporte  
 c  
 c   --------------------------------------------------------------  
   
   
 c   ----------------------------------------  
 c   Transport dans le plan latitude-altitude  
 c   ----------------------------------------  
   
       zvQ=0.  
       psiQ=0.  
       do iQ=1,nQ  
          zvQtmp=0.  
          do l=1,llm  
             do j=1,jjm  
 c              print*,'j,l,iQ=',j,l,iQ  
 c   Calcul des moyennes zonales du transort total et de zvQtmp  
                do i=1,iim  
                   zvQ(j,l,itot,iQ)=zvQ(j,l,itot,iQ)  
      s                            +flux_vQ_cum(i,j,l,iQ)  
                   zqy=      0.5*(Q_cum(i,j,l,iQ)*masse_cum(i,j,l)+  
      s                           Q_cum(i,j+1,l,iQ)*masse_cum(i,j+1,l))  
                   zvQtmp(j,l)=zvQtmp(j,l)+flux_v_cum(i,j,l)*zqy  
      s             /(0.5*(masse_cum(i,j,l)+masse_cum(i,j+1,l)))  
                   zvQ(j,l,iave,iQ)=zvQ(j,l,iave,iQ)+zqy  
                enddo  
 c              print*,'aOK'  
 c   Decomposition  
                zvQ(j,l,iave,iQ)=zvQ(j,l,iave,iQ)/zmasse(j,l)  
                zvQ(j,l,itot,iQ)=zvQ(j,l,itot,iQ)*zfactv(j,l)  
                zvQtmp(j,l)=zvQtmp(j,l)*zfactv(j,l)  
                zvQ(j,l,immc,iQ)=zv(j,l)*zvQ(j,l,iave,iQ)*zfactv(j,l)  
                zvQ(j,l,itrs,iQ)=zvQ(j,l,itot,iQ)-zvQtmp(j,l)  
                zvQ(j,l,istn,iQ)=zvQtmp(j,l)-zvQ(j,l,immc,iQ)  
             enddo  
          enddo  
 c   fonction de courant meridienne pour la quantite Q  
          do l=llm,1,-1  
             do j=1,jjm  
                psiQ(j,l,iQ)=psiQ(j,l+1,iQ)+zvQ(j,l,itot,iQ)  
             enddo  
          enddo  
       enddo  
   
 c   fonction de courant pour la circulation meridienne moyenne  
       psi=0.  
       do l=llm,1,-1  
          do j=1,jjm  
             psi(j,l)=psi(j,l+1)+zv(j,l)  
             zv(j,l)=zv(j,l)*zfactv(j,l)  
          enddo  
       enddo  
   
 c     print*,'4OK'  
 c   sorties proprement dites  
       if (i_sortie.eq.1) then  
       do iQ=1,nQ  
          do itr=1,ntr  
             call histwrite(fileid,znom(itr,iQ),itau,zvQ(:,:,itr,iQ))  
          enddo  
          call histwrite(fileid,'psi'//nom(iQ),itau,psiQ(:,1:llm,iQ))  
       enddo  
   
       call histwrite(fileid,'masse',itau,zmasse)  
       call histwrite(fileid,'v',itau,zv)  
       psi=psi*1.e-9  
       call histwrite(fileid,'psi',itau,psi(:,1:llm))  
   
       endif  
   
   
 c   -----------------  
 c   Moyenne verticale  
 c   -----------------  
   
       zamasse=0.  
       do l=1,llm  
          zamasse(:)=zamasse(:)+zmasse(:,l)  
       enddo  
       zavQ=0.  
       do iQ=1,nQ  
          do itr=2,ntr  
             do l=1,llm  
                zavQ(:,itr,iQ)=zavQ(:,itr,iQ)+zvQ(:,l,itr,iQ)*zmasse(:,l)  
             enddo  
             zavQ(:,itr,iQ)=zavQ(:,itr,iQ)/zamasse(:)  
             call histwrite(fileid,'a'//znom(itr,iQ),itau,zavQ(:,itr,iQ))  
          enddo  
       enddo  
   
 c     on doit pouvoir tracer systematiquement la fonction de courant.  
   
 c=====================================================================  
 c/////////////////////////////////////////////////////////////////////  
       icum=0                  !///////////////////////////////////////  
       endif ! icum.eq.ncum    !///////////////////////////////////////  
 c/////////////////////////////////////////////////////////////////////  
 c=====================================================================  
2    
3        return    IMPLICIT NONE
4        end  
5    contains
6    
7      SUBROUTINE bilan_dyn(ps, masse, pk, flux_u, flux_v, teta, phi, ucov, vcov, &
8           trac)
9    
10        ! From LMDZ4/libf/dyn3d/bilan_dyn.F, version 1.5 2005/03/16 10:12:17
11    
12        ! Sous-programme consacré à des diagnostics dynamiques de base.
13        ! De façon générale, les moyennes des scalaires Q sont pondérées
14        ! par la masse. Les flux de masse sont, eux, simplement moyennés.
15    
16        USE comconst, ONLY: cpp
17        USE comgeom, ONLY: constang_2d, cu_2d, cv_2d
18        USE dimens_m, ONLY: iim, jjm, llm
19        USE histwrite_m, ONLY: histwrite
20        use init_dynzon_m, only: ncum, fileid, znom, ntr, nq, nom
21        USE paramet_m, ONLY: iip1, jjp1
22    
23        ! Arguments:
24    
25        real, intent(in):: ps(iip1, jjp1)
26        real, intent(in):: masse(iip1, jjp1, llm), pk(iip1, jjp1, llm)
27        real, intent(in):: flux_u(iip1, jjp1, llm)
28        real, intent(in):: flux_v(iip1, jjm, llm)
29        real, intent(in):: teta(iip1, jjp1, llm)
30        real, intent(in):: phi(iip1, jjp1, llm)
31        real, intent(in):: ucov(iip1, jjp1, llm)
32        real, intent(in):: vcov(iip1, jjm, llm)
33        real, intent(in):: trac(:, :, :) ! (iim + 1, jjm + 1, llm)
34    
35        ! Local:
36    
37        integer:: icum  = 0
38        integer:: itau = 0
39        real zqy, zfactv(jjm, llm)
40    
41        real ww
42    
43        ! Variables dynamiques intermédiaires
44        REAL vcont(iip1, jjm, llm), ucont(iip1, jjp1, llm)
45        REAL ang(iip1, jjp1, llm), unat(iip1, jjp1, llm)
46        REAL massebx(iip1, jjp1, llm), masseby(iip1, jjm, llm)
47        REAL w(iip1, jjp1, llm), ecin(iip1, jjp1, llm), convm(iip1, jjp1, llm)
48    
49        ! Champ contenant les scalaires advectés
50        real Q(iip1, jjp1, llm, nQ)
51    
52        ! Champs cumulés
53        real, save:: ps_cum(iip1, jjp1)
54        real, save:: masse_cum(iip1, jjp1, llm)
55        real, save:: flux_u_cum(iip1, jjp1, llm)
56        real, save:: flux_v_cum(iip1, jjm, llm)
57        real, save:: Q_cum(iip1, jjp1, llm, nQ)
58        real, save:: flux_uQ_cum(iip1, jjp1, llm, nQ)
59        real, save:: flux_vQ_cum(iip1, jjm, llm, nQ)
60        real dQ(iip1, jjp1, llm, nQ)
61    
62        ! champs de tansport en moyenne zonale
63        integer itr
64        integer, parameter:: iave = 1, itot = 2, immc = 3, itrs = 4, istn = 5
65    
66        real zvQ(jjm, llm, ntr, nQ), zvQtmp(jjm, llm)
67        real zavQ(jjm, 2: ntr, nQ), psiQ(jjm, llm + 1, nQ)
68        real zmasse(jjm, llm)
69        real zv(jjm, llm), psi(jjm, llm + 1)
70        integer i, j, l, iQ
71    
72        !-----------------------------------------------------------------
73    
74        ! Calcul des champs dynamiques
75    
76        ! Énergie cinétique
77        ucont = 0
78        CALL covcont(llm, ucov, vcov, ucont, vcont)
79        CALL enercin(vcov, ucov, vcont, ucont, ecin)
80    
81        ! moment cinétique
82        do l = 1, llm
83           ang(:, :, l) = ucov(:, :, l) + constang_2d
84           unat(:, :, l) = ucont(:, :, l)*cu_2d
85        enddo
86    
87        Q(:, :, :, 1) = teta * pk / cpp
88        Q(:, :, :, 2) = phi
89        Q(:, :, :, 3) = ecin
90        Q(:, :, :, 4) = ang
91        Q(:, :, :, 5) = unat
92        Q(:, :, :, 6) = trac
93        Q(:, :, :, 7) = 1.
94    
95        ! Cumul
96    
97        if (icum == 0) then
98           ps_cum = 0.
99           masse_cum = 0.
100           flux_u_cum = 0.
101           flux_v_cum = 0.
102           Q_cum = 0.
103           flux_vQ_cum = 0.
104           flux_uQ_cum = 0.
105        endif
106    
107        itau = itau + 1
108        icum = icum + 1
109    
110        ! Accumulation des flux de masse horizontaux
111        ps_cum = ps_cum + ps
112        masse_cum = masse_cum + masse
113        flux_u_cum = flux_u_cum + flux_u
114        flux_v_cum = flux_v_cum + flux_v
115        do iQ = 1, nQ
116           Q_cum(:, :, :, iQ) = Q_cum(:, :, :, iQ) + Q(:, :, :, iQ)*masse
117        enddo
118    
119        ! FLUX ET TENDANCES
120    
121        ! Flux longitudinal
122        forall (iQ = 1: nQ, i = 1: iim) flux_uQ_cum(i, :, :, iQ) &
123             = flux_uQ_cum(i, :, :, iQ) &
124             + flux_u(i, :, :) * 0.5 * (Q(i, :, :, iQ) + Q(i + 1, :, :, iQ))
125        flux_uQ_cum(iip1, :, :, :) = flux_uQ_cum(1, :, :, :)
126    
127        ! Flux méridien
128        forall (iQ = 1: nQ, j = 1: jjm) flux_vQ_cum(:, j, :, iQ) &
129             = flux_vQ_cum(:, j, :, iQ) &
130             + flux_v(:, j, :) * 0.5 * (Q(:, j, :, iQ) + Q(:, j + 1, :, iQ))
131    
132        ! tendances
133    
134        ! convergence horizontale
135        call convflu(flux_uQ_cum, flux_vQ_cum, llm*nQ, dQ)
136    
137        ! calcul de la vitesse verticale
138        call convmas(flux_u_cum, flux_v_cum, convm)
139        CALL vitvert(convm, w)
140    
141        do iQ = 1, nQ
142           do l = 1, llm-1
143              do j = 1, jjp1
144                 do i = 1, iip1
145                    ww = -0.5*w(i, j, l + 1)*(Q(i, j, l, iQ) + Q(i, j, l + 1, iQ))
146                    dQ(i, j, l, iQ) = dQ(i, j, l, iQ)-ww
147                    dQ(i, j, l + 1, iQ) = dQ(i, j, l + 1, iQ) + ww
148                 enddo
149              enddo
150           enddo
151        enddo
152    
153        ! PAS DE TEMPS D'ECRITURE
154    
155        writing_step: if (icum == ncum) then
156           ! Normalisation
157           do iQ = 1, nQ
158              Q_cum(:, :, :, iQ) = Q_cum(:, :, :, iQ)/masse_cum
159           enddo
160           ps_cum = ps_cum / ncum
161           masse_cum = masse_cum / ncum
162           flux_u_cum = flux_u_cum / ncum
163           flux_v_cum = flux_v_cum / ncum
164           flux_uQ_cum = flux_uQ_cum / ncum
165           flux_vQ_cum = flux_vQ_cum / ncum
166           dQ = dQ / ncum
167    
168           ! A retravailler eventuellement
169           ! division de dQ par la masse pour revenir aux bonnes grandeurs
170           do iQ = 1, nQ
171              dQ(:, :, :, iQ) = dQ(:, :, :, iQ)/masse_cum
172           enddo
173    
174           ! Transport méridien
175    
176           ! cumul zonal des masses des mailles
177    
178           zv = 0.
179           zmasse = 0.
180           call massbar(masse_cum, massebx, masseby)
181           do l = 1, llm
182              do j = 1, jjm
183                 do i = 1, iim
184                    zmasse(j, l) = zmasse(j, l) + masseby(i, j, l)
185                    zv(j, l) = zv(j, l) + flux_v_cum(i, j, l)
186                 enddo
187                 zfactv(j, l) = cv_2d(1, j)/zmasse(j, l)
188              enddo
189           enddo
190    
191           ! Transport dans le plan latitude-altitude
192    
193           zvQ = 0.
194           psiQ = 0.
195           do iQ = 1, nQ
196              zvQtmp = 0.
197              do l = 1, llm
198                 do j = 1, jjm
199                    ! Calcul des moyennes zonales du transort total et de zvQtmp
200                    do i = 1, iim
201                       zvQ(j, l, itot, iQ) = zvQ(j, l, itot, iQ) &
202                            + flux_vQ_cum(i, j, l, iQ)
203                       zqy =  0.5 * (Q_cum(i, j, l, iQ) * masse_cum(i, j, l) &
204                            + Q_cum(i, j + 1, l, iQ) * masse_cum(i, j + 1, l))
205                       zvQtmp(j, l) = zvQtmp(j, l) + flux_v_cum(i, j, l) * zqy &
206                            / (0.5 * (masse_cum(i, j, l) + masse_cum(i, j + 1, l)))
207                       zvQ(j, l, iave, iQ) = zvQ(j, l, iave, iQ) + zqy
208                    enddo
209                    ! Decomposition
210                    zvQ(j, l, iave, iQ) = zvQ(j, l, iave, iQ)/zmasse(j, l)
211                    zvQ(j, l, itot, iQ) = zvQ(j, l, itot, iQ)*zfactv(j, l)
212                    zvQtmp(j, l) = zvQtmp(j, l)*zfactv(j, l)
213                    zvQ(j, l, immc, iQ) = zv(j, l)*zvQ(j, l, iave, iQ)*zfactv(j, l)
214                    zvQ(j, l, itrs, iQ) = zvQ(j, l, itot, iQ)-zvQtmp(j, l)
215                    zvQ(j, l, istn, iQ) = zvQtmp(j, l)-zvQ(j, l, immc, iQ)
216                 enddo
217              enddo
218              ! fonction de courant meridienne pour la quantite Q
219              do l = llm, 1, -1
220                 do j = 1, jjm
221                    psiQ(j, l, iQ) = psiQ(j, l + 1, iQ) + zvQ(j, l, itot, iQ)
222                 enddo
223              enddo
224           enddo
225    
226           ! fonction de courant pour la circulation meridienne moyenne
227           psi = 0.
228           do l = llm, 1, -1
229              do j = 1, jjm
230                 psi(j, l) = psi(j, l + 1) + zv(j, l)
231                 zv(j, l) = zv(j, l)*zfactv(j, l)
232              enddo
233           enddo
234    
235           ! sorties proprement dites
236           do iQ = 1, nQ
237              do itr = 1, ntr
238                 call histwrite(fileid, znom(itr, iQ), itau, zvQ(:, :, itr, iQ))
239              enddo
240              call histwrite(fileid, 'psi'//nom(iQ), itau, psiQ(:, :llm, iQ))
241           enddo
242    
243           call histwrite(fileid, 'masse', itau, zmasse)
244           call histwrite(fileid, 'v', itau, zv)
245           psi = psi*1.e-9
246           call histwrite(fileid, 'psi', itau, psi(:, :llm))
247    
248           ! Intégrale verticale
249    
250           forall (iQ = 1: nQ, itr = 2: ntr) zavQ(:, itr, iQ) &
251                = sum(zvQ(:, :, itr, iQ) * zmasse, dim=2) / cv_2d(1, :)
252    
253           do iQ = 1, nQ
254              do itr = 2, ntr
255                 call histwrite(fileid, 'a'//znom(itr, iQ), itau, zavQ(:, itr, iQ))
256              enddo
257           enddo
258    
259           ! On doit pouvoir tracer systematiquement la fonction de courant.
260           icum = 0
261        endif writing_step
262    
263      end SUBROUTINE bilan_dyn
264    
265    end module bilan_dyn_m

Legend:
Removed from v.30  
changed lines
  Added in v.57

  ViewVC Help
Powered by ViewVC 1.1.21