source: LMDZ5/trunk/libf/dyn3dpar/exner_milieu_p.F @ 1578

Last change on this file since 1578 was 1559, checked in by Ehouarn Millour, 13 years ago

Bug correction: add OpenMP synchronizations (same story as for exner_hyb_p bug correction of rev 1557).
EM

File size: 5.8 KB
Line 
1!
2! $Id $
3!
4      SUBROUTINE  exner_milieu_p ( ngrid, ps, p,beta, pks, pk, pkf )
5c
6c     Auteurs :  F. Forget , Y. Wanherdrick
7c P.Le Van  , Fr. Hourdin  .
8c    ..........
9c
10c    ....  ngrid, ps,p             sont des argum.d'entree  au sous-prog ...
11c    .... beta, pks,pk,pkf   sont des argum.de sortie au sous-prog ...
12c
13c   ************************************************************************
14c    Calcule la fonction d'Exner pk = Cp * (p/preff) ** kappa , aux milieux des
15c    couches .   Pk(l) sera calcule aux milieux  des couches l ,entre les
16c    pressions p(l) et p(l+1) ,definis aux interfaces des llm couches .
17c   ************************************************************************
18c    .. N.B : Au sommet de l'atmosphere,  p(llm+1) = 0. , et ps et pks sont
19c    la pression et la fonction d'Exner  au  sol  .
20c
21c     WARNING : CECI est une version speciale de exner_hyb originale
22c               Utilise dans la version martienne pour pouvoir
23c               tourner avec des coordonnees verticales complexe
24c              => Il ne verifie PAS la condition la proportionalite en
25c              energie totale/ interne / potentielle (F.Forget 2001)
26c    ( voir note de Fr.Hourdin )  ,
27c
28      USE parallel
29      IMPLICIT NONE
30c
31#include "dimensions.h"
32#include "paramet.h"
33#include "comconst.h"
34#include "comgeom.h"
35#include "comvert.h"
36#include "serre.h"
37
38      INTEGER  ngrid
39      REAL p(ngrid,llmp1),pk(ngrid,llm),pkf(ngrid,llm)
40      REAL ps(ngrid),pks(ngrid), beta(ngrid,llm)
41
42c    .... variables locales   ...
43
44      INTEGER l, ij
45      REAL dum1
46
47      REAL ppn(iim),pps(iim)
48      REAL xpn, xps
49      REAL SSUM
50      EXTERNAL SSUM
51      INTEGER ije,ijb,jje,jjb
52      logical,save :: firstcall=.true.
53!$OMP THREADPRIVATE(firstcall)
54      character(len=*),parameter :: modname="exner_milieu_p"
55
56      ! Sanity check
57      if (firstcall) then
58        ! check that vertical discretization is compatible
59        ! with this routine
60        if (disvert_type.ne.2) then
61          call abort_gcm(modname,
62     &     "this routine should only be called if disvert_type==2",42)
63        endif
64       
65        ! sanity checks for Shallow Water case (1 vertical layer)
66        if (llm.eq.1) then
67          if (kappa.ne.1) then
68            call abort_gcm(modname,
69     &      "kappa!=1 , but running in Shallow Water mode!!",42)
70          endif
71          if (cpp.ne.r) then
72            call abort_gcm(modname,
73     &      "cpp!=r , but running in Shallow Water mode!!",42)
74          endif
75        endif ! of if (llm.eq.1)
76
77        firstcall=.false.
78      endif ! of if (firstcall)
79     
80c$OMP BARRIER
81
82! Specific behaviour for Shallow Water (1 vertical layer) case
83      if (llm.eq.1) then
84             
85        ! Compute pks(:),pk(:),pkf(:)
86        ijb=ij_begin
87        ije=ij_end
88!$OMP DO SCHEDULE(STATIC)
89        DO ij=ijb, ije
90          pks(ij)=(cpp/preff)*ps(ij)
91          pk(ij,1) = .5*pks(ij)
92          pkf(ij,1)=pk(ij,1)
93        ENDDO
94!$OMP ENDDO
95
96!$OMP MASTER
97      if (pole_nord) then
98        DO  ij   = 1, iim
99          ppn(ij) = aire(   ij   ) * pks(  ij     )
100        ENDDO
101        xpn      = SSUM(iim,ppn,1) /apoln
102 
103        DO ij   = 1, iip1
104          pks(   ij     )  =  xpn
105          pk(ij,1) = .5*pks(ij)
106          pkf(ij,1)=pk(ij,1)
107        ENDDO
108      endif
109     
110      if (pole_sud) then
111        DO  ij   = 1, iim
112          pps(ij) = aire(ij+ip1jm) * pks(ij+ip1jm )
113        ENDDO
114        xps      = SSUM(iim,pps,1) /apols
115 
116        DO ij   = 1, iip1
117          pks( ij+ip1jm )  =  xps
118          pk(ij+ip1jm,1)=.5*pks(ij+ip1jm)
119          pkf(ij+ip1jm,1)=pk(ij+ip1jm,1)
120        ENDDO
121      endif
122!$OMP END MASTER
123!$OMP BARRIER
124        jjb=jj_begin
125        jje=jj_end
126        CALL filtreg_p ( pkf,jjb,jje, jmp1, llm, 2, 1, .TRUE., 1 )
127
128        ! our work is done, exit routine
129        return
130      endif ! of if (llm.eq.1)
131
132!!!! General case:
133
134c     -------------
135c     Calcul de pks
136c     -------------
137   
138      ijb=ij_begin
139      ije=ij_end
140
141c$OMP DO SCHEDULE(STATIC)
142      DO   ij  = ijb, ije
143        pks(ij) = cpp * ( ps(ij)/preff ) ** kappa
144      ENDDO
145c$OMP ENDDO
146c Synchro OPENMP ici
147
148c$OMP MASTER
149      if (pole_nord) then
150        DO  ij   = 1, iim
151          ppn(ij) = aire(   ij   ) * pks(  ij     )
152        ENDDO
153        xpn      = SSUM(iim,ppn,1) /apoln
154 
155        DO ij   = 1, iip1
156          pks(   ij     )  =  xpn
157        ENDDO
158      endif
159     
160      if (pole_sud) then
161        DO  ij   = 1, iim
162          pps(ij) = aire(ij+ip1jm) * pks(ij+ip1jm )
163        ENDDO
164        xps      = SSUM(iim,pps,1) /apols
165 
166        DO ij   = 1, iip1
167          pks( ij+ip1jm )  =  xps
168        ENDDO
169      endif
170c$OMP END MASTER
171c$OMP BARRIER
172c
173c
174c    .... Calcul de pk  pour la couche l
175c    --------------------------------------------
176c
177      dum1 = cpp * (2*preff)**(-kappa)
178      DO l = 1, llm-1
179c$OMP DO SCHEDULE(STATIC)
180        DO   ij   = ijb, ije
181         pk(ij,l) = dum1 * (p(ij,l) + p(ij,l+1))**kappa
182        ENDDO
183c$OMP ENDDO NOWAIT       
184      ENDDO
185
186c    .... Calcul de pk  pour la couche l = llm ..
187c    (on met la meme distance (en log pression)  entre Pk(llm)
188c    et Pk(llm -1) qu'entre Pk(llm-1) et Pk(llm-2)
189
190c$OMP DO SCHEDULE(STATIC)
191      DO   ij   = ijb, ije
192         pk(ij,llm) = pk(ij,llm-1)**2 / pk(ij,llm-2)
193      ENDDO
194c$OMP ENDDO NOWAIT       
195
196
197c    calcul de pkf
198c    -------------
199c      CALL SCOPY   ( ngrid * llm, pk, 1, pkf, 1 )
200      DO l = 1, llm
201c$OMP DO SCHEDULE(STATIC)
202         DO   ij   = ijb, ije
203           pkf(ij,l)=pk(ij,l)
204         ENDDO
205c$OMP ENDDO NOWAIT             
206      ENDDO
207
208c$OMP BARRIER
209     
210      jjb=jj_begin
211      jje=jj_end
212      CALL filtreg_p ( pkf,jjb,jje, jmp1, llm, 2, 1, .TRUE., 1 )
213     
214c    EST-CE UTILE ?? : calcul de beta
215c    --------------------------------
216      DO l = 2, llm
217c$OMP DO SCHEDULE(STATIC)
218        DO   ij   = ijb, ije
219          beta(ij,l) = pk(ij,l) / pk(ij,l-1)   
220        ENDDO
221c$OMP ENDDO NOWAIT             
222      ENDDO
223
224      RETURN
225      END
Note: See TracBrowser for help on using the repository browser.