source: dynamico_lmdz/aquaplanet/LMDZ5_old/libf/dynlonlat_phylonlat/calfis_loc.F @ 4020

Last change on this file since 4020 was 3836, checked in by ymipsl, 10 years ago

Update physic call interface.
YM

File size: 31.2 KB
Line 
1!
2! $Id$
3!
4C
5C
6      SUBROUTINE calfis_loc(lafin,
7     $                  jD_cur, jH_cur,
8     $                  pucov,
9     $                  pvcov,
10     $                  pteta,
11     $                  pq,
12     $                  pmasse,
13     $                  pps,
14     $                  pp,
15     $                  ppk,
16     $                  pphis,
17     $                  pphi,
18     $                  pducov,
19     $                  pdvcov,
20     $                  pdteta,
21     $                  pdq,
22     $                  flxw,
23     $                  pdufi,
24     $                  pdvfi,
25     $                  pdhfi,
26     $                  pdqfi,
27     $                  pdpsfi)
28#ifdef CPP_PHYS
29! If using physics
30c
31c    Auteur :  P. Le Van, F. Hourdin
32c   .........
33      USE dimphy
34      USE mod_phys_lmdz_mpi_data, mpi_root_xx=>mpi_master
35      USE mod_phys_lmdz_omp_data, ONLY: klon_omp, klon_omp_begin
36      USE mod_const_mpi, ONLY: COMM_LMDZ
37      USE mod_interface_dyn_phys
38      USE IOPHY
39#endif
40#ifdef CPP_PARA
41      USE parallel_lmdz,ONLY:omp_chunk,using_mpi,jjb_u,jje_u,jjb_v,jje_v
42      USE Write_Field
43      Use Write_field_p
44      USE Times
45#endif
46      USE infotrac, ONLY: nqtot, niadv, tname
47      USE control_mod, ONLY: planet_type, nsplit_phys
48
49#ifdef CPP_PARA
50      IMPLICIT NONE
51c=======================================================================
52c
53c   1. rearrangement des tableaux et transformation
54c      variables dynamiques  >  variables physiques
55c   2. calcul des termes physiques
56c   3. retransformation des tendances physiques en tendances dynamiques
57c
58c   remarques:
59c   ----------
60c
61c    - les vents sont donnes dans la physique par leurs composantes
62c      naturelles.
63c    - la variable thermodynamique de la physique est une variable
64c      intensive :   T
65c      pour la dynamique on prend    T * ( preff / p(l) ) **kappa
66c    - les deux seules variables dependant de la geometrie necessaires
67c      pour la physique sont la latitude pour le rayonnement et
68c      l'aire de la maille quand on veut integrer une grandeur
69c      horizontalement.
70c    - les points de la physique sont les points scalaires de la
71c      la dynamique; numerotation:
72c          1 pour le pole nord
73c          (jjm-1)*iim pour l'interieur du domaine
74c          ngridmx pour le pole sud
75c      ---> ngridmx=2+(jjm-1)*iim
76c
77c     Input :
78c     -------
79c       ecritphy        frequence d'ecriture (en jours)de histphy
80c       pucov           covariant zonal velocity
81c       pvcov           covariant meridional velocity
82c       pteta           potential temperature
83c       pps             surface pressure
84c       pmasse          masse d'air dans chaque maille
85c       pts             surface temperature  (K)
86c       callrad         clef d'appel au rayonnement
87c
88c    Output :
89c    --------
90c        pdufi          tendency for the natural zonal velocity (ms-1)
91c        pdvfi          tendency for the natural meridional velocity
92c        pdhfi          tendency for the potential temperature
93c        pdtsfi         tendency for the surface temperature
94c
95c        pdtrad         radiative tendencies  \  both input
96c        pfluxrad       radiative fluxes      /  and output
97c
98c=======================================================================
99c
100c-----------------------------------------------------------------------
101c
102c    0.  Declarations :
103c    ------------------
104
105#include "dimensions.h"
106#include "paramet.h"
107#include "temps.h"
108
109      INTEGER ngridmx
110      PARAMETER( ngridmx = 2+(jjm-1)*iim - 1/jjm   )
111
112#include "comconst.h"
113#include "comvert.h"
114#include "comgeom2.h"
115#include "iniprint.h"
116#ifdef CPP_MPI
117      include 'mpif.h'
118#endif
119c    Arguments :
120c    -----------
121      LOGICAL,INTENT(IN) ::  lafin ! .true. for the very last call to physics
122      REAL,INTENT(IN):: jD_cur, jH_cur
123      REAL,INTENT(IN):: pvcov(iip1,jjb_v:jje_v,llm) ! covariant meridional velocity
124      REAL,INTENT(IN):: pucov(iip1,jjb_u:jje_u,llm) ! covariant zonal velocity
125      REAL,INTENT(IN):: pteta(iip1,jjb_u:jje_u,llm) ! potential temperature
126      REAL,INTENT(IN):: pmasse(iip1,jjb_u:jje_u,llm) ! mass in each cell ! not used
127      REAL,INTENT(IN):: pq(iip1,jjb_u:jje_u,llm,nqtot) ! tracers
128      REAL,INTENT(IN):: pphis(iip1,jjb_u:jje_u) ! surface geopotential
129      REAL,INTENT(IN):: pphi(iip1,jjb_u:jje_u,llm) ! geopotential
130
131      REAL,INTENT(IN) :: pdvcov(iip1,jjb_v:jje_v,llm) ! dynamical tendency on vcov ! not used
132      REAL,INTENT(IN) :: pducov(iip1,jjb_u:jje_u,llm) ! dynamical tendency on ucov
133      REAL,INTENT(IN) :: pdteta(iip1,jjb_u:jje_u,llm) ! dynamical tendency on teta ! not used
134      REAL,INTENT(IN) :: pdq(iip1,jjb_u:jje_u,llm,nqtot) ! dynamical tendency on tracers ! not used
135
136      REAL,INTENT(IN) :: pps(iip1,jjb_u:jje_u) ! surface pressure (Pa)
137      REAL,INTENT(IN) :: pp(iip1,jjb_u:jje_u,llmp1) ! pressure at mesh interfaces (Pa)
138      REAL,INTENT(IN) :: ppk(iip1,jjb_u:jje_u,llm) ! Exner at mid-layer
139      REAL,INTENT(IN) :: flxw(iip1,jjb_u:jje_u,llm)  ! Vertical mass flux on dynamics grid
140
141      ! tendencies (in */s) from the physics
142      REAL,INTENT(OUT) :: pdvfi(iip1,jjb_v:jje_v,llm) ! tendency on covariant meridional wind
143      REAL,INTENT(OUT) :: pdufi(iip1,jjb_u:jje_u,llm) ! tendency on covariant zonal wind
144      REAL,INTENT(OUT) :: pdhfi(iip1,jjb_u:jje_u,llm) ! tendency on potential temperature (K/s)
145      REAL,INTENT(OUT) :: pdqfi(iip1,jjb_u:jje_u,llm,nqtot) ! tendency on tracers
146      REAL,INTENT(OUT) :: pdpsfi(iip1,jjb_u:jje_u) ! tendency on surface pressure (Pa/s)
147
148#ifdef CPP_PHYS
149! Ehouarn: for now calfis_p needs some informations from physics to compile
150c    Local variables :
151c    -----------------
152
153      INTEGER i,j,l,ig0,ig,iq,iiq
154      REAL,ALLOCATABLE,SAVE :: zpsrf(:)
155      REAL,ALLOCATABLE,SAVE :: zplev(:,:),zplay(:,:)
156      REAL,ALLOCATABLE,SAVE :: zphi(:,:),zphis(:)
157c
158      REAL,ALLOCATABLE,SAVE :: zufi(:,:), zvfi(:,:)
159      REAL,ALLOCATABLE,SAVE :: ztfi(:,:),zqfi(:,:,:)
160c
161      REAL,ALLOCATABLE,SAVE :: pcvgu(:,:), pcvgv(:,:)
162      REAL,ALLOCATABLE,SAVE :: pcvgt(:,:), pcvgq(:,:,:)
163c
164      REAL,ALLOCATABLE,SAVE :: zdufi(:,:),zdvfi(:,:)
165      REAL,ALLOCATABLE,SAVE :: zdtfi(:,:),zdqfi(:,:,:)
166      REAL,ALLOCATABLE,SAVE :: zdpsrf(:)
167      REAL,SAVE,ALLOCATABLE ::  flxwfi(:,:)     ! Flux de masse verticale sur la grille physiq
168
169c
170      REAL,ALLOCATABLE,SAVE :: zplev_omp(:,:)
171      REAL,ALLOCATABLE,SAVE :: zplay_omp(:,:)
172      REAL,ALLOCATABLE,SAVE :: zphi_omp(:,:)
173      REAL,ALLOCATABLE,SAVE :: zphis_omp(:)
174      REAL,ALLOCATABLE,SAVE :: presnivs_omp(:)
175      REAL,ALLOCATABLE,SAVE :: zufi_omp(:,:)
176      REAL,ALLOCATABLE,SAVE :: zvfi_omp(:,:)
177      REAL,ALLOCATABLE,SAVE :: ztfi_omp(:,:)
178      REAL,ALLOCATABLE,SAVE :: zqfi_omp(:,:,:)
179      REAL,ALLOCATABLE,SAVE :: zdufi_omp(:,:)
180      REAL,ALLOCATABLE,SAVE :: zdvfi_omp(:,:)
181      REAL,ALLOCATABLE,SAVE :: zdtfi_omp(:,:)
182      REAL,ALLOCATABLE,SAVE :: zdqfi_omp(:,:,:)
183      REAL,ALLOCATABLE,SAVE :: zdpsrf_omp(:)
184      REAL,SAVE,ALLOCATABLE ::  flxwfi_omp(:,:)     ! Flux de masse verticale sur la grille physiq
185
186!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
187! Introduction du splitting (FH)
188! Question pour Yann :
189! J'ai été surpris au début que les tableaux zufi_omp, zdufi_omp n'co soitent
190! en SAVE. Je crois comprendre que c'est parce que tu voulais qu'il
191! soit allocatable (plutot par exemple que de passer une dimension
192! dépendant du process en argument des routines) et que, du coup,
193! le SAVE évite d'avoir à refaire l'allocation à chaque appel.
194! Tu confirmes ?
195! J'ai suivi le même principe pour les zdufic_omp
196! Mais c'est surement bien que tu controles.
197!
198
199      REAL,ALLOCATABLE,SAVE :: zdufic_omp(:,:)
200      REAL,ALLOCATABLE,SAVE :: zdvfic_omp(:,:)
201      REAL,ALLOCATABLE,SAVE :: zdtfic_omp(:,:)
202      REAL,ALLOCATABLE,SAVE :: zdqfic_omp(:,:,:)
203      REAL jH_cur_split,zdt_split
204      LOGICAL debut_split,lafin_split
205      INTEGER isplit
206!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
207
208c$OMP THREADPRIVATE(zplev_omp,zplay_omp,zphi_omp,zphis_omp,
209c$OMP+                 presnivs_omp,zufi_omp,zvfi_omp,ztfi_omp,
210c$OMP+                 zqfi_omp,zdufi_omp,zdvfi_omp,
211c$OMP+                 zdtfi_omp,zdqfi_omp,zdpsrf_omp,flxwfi_omp,
212c$OMP+                 zdufic_omp,zdvfic_omp,zdtfic_omp,zdqfic_omp)       
213
214      LOGICAL,SAVE :: first_omp=.true.
215c$OMP THREADPRIVATE(first_omp)
216     
217      REAL zsin(iim),zcos(iim),z1(iim)
218      REAL zsinbis(iim),zcosbis(iim),z1bis(iim)
219      REAL unskap, pksurcp
220c
221      REAL SSUM
222
223      LOGICAL,SAVE :: firstcal=.true., debut=.true.
224c$OMP THREADPRIVATE(firstcal,debut)
225     
226      REAL,SAVE,dimension(1:iim,1:llm):: du_send,du_recv,dv_send,dv_recv
227      INTEGER :: ierr
228#ifdef CPP_MPI
229      INTEGER,dimension(MPI_STATUS_SIZE,4) :: Status
230#else
231      INTEGER,dimension(1,4) :: Status
232#endif
233      INTEGER, dimension(4) :: Req
234      REAL,ALLOCATABLE,SAVE:: zdufi2(:,:),zdvfi2(:,:)
235      integer :: k,kstart,kend
236      INTEGER :: offset
237
238      LOGICAL tracerdyn 
239c
240c-----------------------------------------------------------------------
241c
242c    1. Initialisations :
243c    --------------------
244c
245
246      klon=klon_mpi
247     
248c
249      IF ( firstcal )  THEN
250        debut = .TRUE.
251        IF (ngridmx.NE.2+(jjm-1)*iim) THEN
252          write(lunout,*) 'STOP dans calfis'
253          write(lunout,*) 
254     &   'La dimension ngridmx doit etre egale a 2 + (jjm-1)*iim'
255          write(lunout,*) '  ngridmx  jjm   iim   '
256          write(lunout,*) ngridmx,jjm,iim
257          STOP
258        ENDIF
259c$OMP MASTER
260      ALLOCATE(zpsrf(klon))
261      ALLOCATE(zplev(klon,llm+1),zplay(klon,llm))
262      ALLOCATE(zphi(klon,llm),zphis(klon))
263      ALLOCATE(zufi(klon,llm), zvfi(klon,llm))
264      ALLOCATE(ztfi(klon,llm),zqfi(klon,llm,nqtot))
265      ALLOCATE(pcvgu(klon,llm), pcvgv(klon,llm))
266      ALLOCATE(pcvgt(klon,llm), pcvgq(klon,llm,2))
267      ALLOCATE(zdufi(klon,llm),zdvfi(klon,llm))
268      ALLOCATE(zdtfi(klon,llm),zdqfi(klon,llm,nqtot))
269      ALLOCATE(zdpsrf(klon))
270      ALLOCATE(zdufi2(klon+iim,llm),zdvfi2(klon+iim,llm))
271      ALLOCATE(flxwfi(klon,llm))
272c$OMP END MASTER
273c$OMP BARRIER     
274      ELSE
275          debut = .FALSE.
276      ENDIF
277
278c
279c
280c-----------------------------------------------------------------------
281c   40. transformation des variables dynamiques en variables physiques:
282c   ---------------------------------------------------------------
283
284c   41. pressions au sol (en Pascals)
285c   ----------------------------------
286
287c$OMP MASTER
288      call start_timer(timer_physic)
289c$OMP END MASTER
290
291c$OMP MASTER             
292!CDIR ON_ADB(index_i)
293!CDIR ON_ADB(index_j)
294      do ig0=1,klon
295        i=index_i(ig0)
296        j=index_j(ig0)
297        zpsrf(ig0)=pps(i,j)
298      enddo
299c$OMP END MASTER
300
301
302c   42. pression intercouches :
303c
304c   -----------------------------------------------------------------
305c     .... zplev  definis aux (llm +1) interfaces des couches  ....
306c     .... zplay  definis aux (  llm )    milieux des couches  ....
307c   -----------------------------------------------------------------
308
309c    ...    Exner = cp * ( p(l) / preff ) ** kappa     ....
310c
311       unskap   = 1./ kappa
312c
313c      print *,omp_rank,'klon--->',klon
314c$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
315      DO l = 1, llmp1
316!CDIR ON_ADB(index_i)
317!CDIR ON_ADB(index_j)
318        do ig0=1,klon
319          i=index_i(ig0)
320          j=index_j(ig0)
321          zplev( ig0,l ) = pp(i,j,l)
322        enddo
323      ENDDO
324c$OMP END DO NOWAIT
325c
326c
327
328c   43. temperature naturelle (en K) et pressions milieux couches .
329c   ---------------------------------------------------------------
330c$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
331      DO l=1,llm
332!CDIR ON_ADB(index_i)
333!CDIR ON_ADB(index_j)
334        do ig0=1,klon
335          i=index_i(ig0)
336          j=index_j(ig0)
337          pksurcp        = ppk(i,j,l) / cpp
338          zplay(ig0,l)   = preff * pksurcp ** unskap
339          ztfi(ig0,l)    = pteta(i,j,l)  * pksurcp
340        enddo
341
342      ENDDO
343c$OMP END DO NOWAIT
344
345c   43.bis traceurs
346c   ---------------
347c
348
349      DO iq=1,nqtot
350         iiq=niadv(iq)
351c$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
352         DO l=1,llm
353!CDIR ON_ADB(index_i)
354!CDIR ON_ADB(index_j)
355           do ig0=1,klon
356             i=index_i(ig0)
357             j=index_j(ig0)
358             zqfi(ig0,l,iq)  = pq(i,j,l,iiq)
359           enddo
360         ENDDO
361c$OMP END DO NOWAIT     
362      ENDDO
363
364
365c   Geopotentiel calcule par rapport a la surface locale:
366c   -----------------------------------------------------
367
368c$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
369         DO l=1,llm
370!CDIR ON_ADB(index_i)
371!CDIR ON_ADB(index_j)
372           do ig0=1,klon
373             i=index_i(ig0)
374             j=index_j(ig0)
375             zphi(ig0,l)  = pphi(i,j,l)
376           enddo
377         ENDDO
378c$OMP END DO NOWAIT     
379
380c      CALL gr_dyn_fi_p(llm,iip1,jjp1,klon,pphi,zphi)
381
382c$OMP MASTER
383!CDIR ON_ADB(index_i)
384!CDIR ON_ADB(index_j)
385           do ig0=1,klon
386             i=index_i(ig0)
387             j=index_j(ig0)
388             zphis(ig0)  = pphis(i,j)
389           enddo
390c$OMP END MASTER
391
392
393c      CALL gr_dyn_fi_p(1,iip1,jjp1,klon,pphis,zphis)
394
395c$OMP BARRIER
396
397c$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
398      DO l=1,llm
399         DO ig=1,klon
400           zphi(ig,l)=zphi(ig,l)-zphis(ig)
401         ENDDO
402      ENDDO
403c$OMP END DO NOWAIT
404     
405
406c
407c   45. champ u:
408c   ------------
409
410      kstart=1
411      kend=klon
412     
413      if (is_north_pole) kstart=2
414      if (is_south_pole) kend=klon-1
415     
416c$OMP DO SCHEDULE(STATIC,OMP_CHUNK)     
417      DO l=1,llm
418!CDIR ON_ADB(index_i)
419!CDIR ON_ADB(index_j)
420!CDIR SPARSE
421        do ig0=kstart,kend
422          i=index_i(ig0)
423          j=index_j(ig0)
424          if (i==1) then
425            zufi(ig0,l)= 0.5 *(  pucov(iim,j,l)/cu(iim,j)
426     $                         + pucov(1,j,l)/cu(1,j) )
427          else
428            zufi(ig0,l)= 0.5*(  pucov(i-1,j,l)/cu(i-1,j)
429     $                       + pucov(i,j,l)/cu(i,j) )
430          endif
431        enddo
432      ENDDO
433c$OMP END DO NOWAIT
434
435c   46.champ v:
436c   -----------
437
438c$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
439      DO l=1,llm
440!CDIR ON_ADB(index_i)
441!CDIR ON_ADB(index_j)
442        DO ig0=kstart,kend
443          i=index_i(ig0)
444          j=index_j(ig0)
445          zvfi(ig0,l)= 0.5 *(  pvcov(i,j-1,l)/cv(i,j-1)
446     $                       + pvcov(i,j,l)/cv(i,j) )
447   
448         ENDDO
449      ENDDO
450c$OMP END DO NOWAIT
451
452c   47. champs de vents aux pole nord   
453c   ------------------------------
454c        U = 1 / pi  *  integrale [ v * cos(long) * d long ]
455c        V = 1 / pi  *  integrale [ v * sin(long) * d long ]
456
457      if (is_north_pole) then
458c$OMP DO SCHEDULE(STATIC,OMP_CHUNK)     
459        DO l=1,llm
460
461           z1(1)   =(rlonu(1)-rlonu(iim)+2.*pi)*pvcov(1,1,l)/cv(1,1)
462           DO i=2,iim
463              z1(i)   =(rlonu(i)-rlonu(i-1))*pvcov(i,1,l)/cv(i,1)
464           ENDDO
465 
466           DO i=1,iim
467              zcos(i)   = COS(rlonv(i))*z1(i)
468              zsin(i)   = SIN(rlonv(i))*z1(i)
469           ENDDO
470 
471           zufi(1,l)  = SSUM(iim,zcos,1)/pi
472           zvfi(1,l)  = SSUM(iim,zsin,1)/pi
473 
474        ENDDO
475c$OMP END DO NOWAIT     
476      endif
477
478
479c   48. champs de vents aux pole sud:
480c   ---------------------------------
481c        U = 1 / pi  *  integrale [ v * cos(long) * d long ]
482c        V = 1 / pi  *  integrale [ v * sin(long) * d long ]
483
484      if (is_south_pole) then
485c$OMP DO SCHEDULE(STATIC,OMP_CHUNK)     
486        DO l=1,llm
487 
488         z1(1)   =(rlonu(1)-rlonu(iim)+2.*pi)*pvcov(1,jjm,l)/cv(1,jjm)
489           DO i=2,iim
490             z1(i)   =(rlonu(i)-rlonu(i-1))*pvcov(i,jjm,l)/cv(i,jjm)
491           ENDDO
492 
493           DO i=1,iim
494              zcos(i)    = COS(rlonv(i))*z1(i)
495              zsin(i)    = SIN(rlonv(i))*z1(i)
496           ENDDO
497 
498           zufi(klon,l)  = SSUM(iim,zcos,1)/pi
499           zvfi(klon,l)  = SSUM(iim,zsin,1)/pi
500        ENDDO
501c$OMP END DO NOWAIT       
502      endif
503
504c On change de grille, dynamique vers physiq, pour le flux de masse verticale
505c$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
506         DO l=1,llm
507!CDIR ON_ADB(index_i)
508!CDIR ON_ADB(index_j)
509           do ig0=1,klon
510             i=index_i(ig0)
511             j=index_j(ig0)
512             flxwfi(ig0,l)  = flxw(i,j,l)
513           enddo
514         ENDDO
515c$OMP END DO NOWAIT
516
517c      CALL gr_dyn_fi_p(llm,iip1,jjp1,klon,flxw,flxwfi)
518
519c-----------------------------------------------------------------------
520c   Appel de la physique:
521c   ---------------------
522
523
524c$OMP BARRIER
525      if (first_omp) then
526        klon=klon_omp
527
528        allocate(zplev_omp(klon,llm+1))
529        allocate(zplay_omp(klon,llm))
530        allocate(zphi_omp(klon,llm))
531        allocate(zphis_omp(klon))
532        allocate(presnivs_omp(llm))
533        allocate(zufi_omp(klon,llm))
534        allocate(zvfi_omp(klon,llm))
535        allocate(ztfi_omp(klon,llm))
536        allocate(zqfi_omp(klon,llm,nqtot))
537        allocate(zdufi_omp(klon,llm))
538        allocate(zdvfi_omp(klon,llm))
539        allocate(zdtfi_omp(klon,llm))
540        allocate(zdqfi_omp(klon,llm,nqtot))
541        allocate(zdufic_omp(klon,llm))
542        allocate(zdvfic_omp(klon,llm))
543        allocate(zdtfic_omp(klon,llm))
544        allocate(zdqfic_omp(klon,llm,nqtot))
545        allocate(zdpsrf_omp(klon))
546        allocate(flxwfi_omp(klon,llm))
547        first_omp=.false.
548      endif
549       
550           
551      klon=klon_omp
552      offset=klon_omp_begin-1
553     
554      do l=1,llm+1
555        do i=1,klon
556          zplev_omp(i,l)=zplev(offset+i,l)
557        enddo
558      enddo
559         
560       do l=1,llm
561        do i=1,klon 
562          zplay_omp(i,l)=zplay(offset+i,l)
563        enddo
564      enddo
565       
566      do l=1,llm
567        do i=1,klon
568          zphi_omp(i,l)=zphi(offset+i,l)
569        enddo
570      enddo
571       
572      do i=1,klon
573        zphis_omp(i)=zphis(offset+i)
574      enddo
575     
576       
577      do l=1,llm
578        presnivs_omp(l)=presnivs(l)
579      enddo
580       
581      do l=1,llm
582        do i=1,klon
583          zufi_omp(i,l)=zufi(offset+i,l)
584        enddo
585      enddo
586       
587      do l=1,llm
588        do i=1,klon
589          zvfi_omp(i,l)=zvfi(offset+i,l)
590        enddo
591      enddo
592       
593      do l=1,llm
594        do i=1,klon
595          ztfi_omp(i,l)=ztfi(offset+i,l)
596        enddo
597      enddo
598       
599      do iq=1,nqtot
600        do l=1,llm
601          do i=1,klon
602            zqfi_omp(i,l,iq)=zqfi(offset+i,l,iq)
603          enddo
604        enddo
605      enddo
606       
607      do l=1,llm
608        do i=1,klon
609          zdufi_omp(i,l)=zdufi(offset+i,l)
610        enddo
611      enddo
612       
613      do l=1,llm
614        do i=1,klon
615          zdvfi_omp(i,l)=zdvfi(offset+i,l)
616        enddo
617      enddo
618       
619      do l=1,llm
620        do i=1,klon
621          zdtfi_omp(i,l)=zdtfi(offset+i,l)
622        enddo
623      enddo
624       
625      do iq=1,nqtot
626        do l=1,llm
627          do i=1,klon
628            zdqfi_omp(i,l,iq)=zdqfi(offset+i,l,iq)
629          enddo
630        enddo
631      enddo
632       
633      do i=1,klon
634        zdpsrf_omp(i)=zdpsrf(offset+i)
635      enddo
636
637      do l=1,llm
638        do i=1,klon
639          flxwfi_omp(i,l)=flxwfi(offset+i,l)
640        enddo
641      enddo
642     
643c$OMP BARRIER
644     
645
646!$OMP MASTER
647!      write(lunout,*) 'PHYSIQUE AVEC NSPLIT_PHYS=',nsplit_phys
648!$OMP END MASTER
649      zdt_split=dtphys/nsplit_phys
650      zdufic_omp(:,:)=0.
651      zdvfic_omp(:,:)=0.
652      zdtfic_omp(:,:)=0.
653      zdqfic_omp(:,:,:)=0.
654
655#ifdef CPP_PHYS
656      do isplit=1,nsplit_phys
657
658         jH_cur_split=jH_cur+(isplit-1) * dtvr / (daysec *nsplit_phys)
659         debut_split=debut.and.isplit==1
660         lafin_split=lafin.and.isplit==nsplit_phys
661
662      if (planet_type=="earth") then
663
664      CALL physiq (klon,
665     .             llm,
666     .             debut_split,
667     .             lafin_split,
668     .             zdt_split,
669     .             zplev_omp,
670     .             zplay_omp,
671     .             zphi_omp,
672     .             zphis_omp,
673     .             presnivs_omp,
674     .             zufi_omp,
675     .             zvfi_omp,
676     .             ztfi_omp,
677     .             zqfi_omp,
678     .             flxwfi_omp,
679     .             zdufi_omp,
680     .             zdvfi_omp,
681     .             zdtfi_omp,
682     .             zdqfi_omp,
683     .             zdpsrf_omp)
684
685      else if ( planet_type=="generic" ) then
686
687      CALL physiq (klon,     !! ngrid
688     .             llm,            !! nlayer
689     .             nqtot,          !! nq
690     .             tname,          !! tracer names from dynamical core (given in infotrac)
691     .             debut_split,    !! firstcall
692     .             lafin_split,    !! lastcall
693     .             jD_cur,         !! pday. see leapfrog_p
694     .             jH_cur_split,   !! ptime "fraction of day"
695     .             zdt_split,      !! ptimestep
696     .             zplev_omp,  !! pplev
697     .             zplay_omp,  !! pplay
698     .             zphi_omp,   !! pphi
699     .             zufi_omp,   !! pu
700     .             zvfi_omp,   !! pv
701     .             ztfi_omp,   !! pt
702     .             zqfi_omp,   !! pq
703     .             flxwfi_omp, !! pw !! or 0. anyway this is for diagnostic. not used in physiq.
704     .             zdufi_omp,  !! pdu
705     .             zdvfi_omp,  !! pdv
706     .             zdtfi_omp,  !! pdt
707     .             zdqfi_omp,  !! pdq
708     .             zdpsrf_omp, !! pdpsrf
709     .             tracerdyn)      !! tracerdyn <-- utilite ???
710
711      endif ! of if (planet_type=="earth")
712
713
714         zufi_omp(:,:)=zufi_omp(:,:)+zdufi_omp(:,:)*zdt_split
715         zvfi_omp(:,:)=zvfi_omp(:,:)+zdvfi_omp(:,:)*zdt_split
716         ztfi_omp(:,:)=ztfi_omp(:,:)+zdtfi_omp(:,:)*zdt_split
717         zqfi_omp(:,:,:)=zqfi_omp(:,:,:)+zdqfi_omp(:,:,:)*zdt_split
718
719         zdufic_omp(:,:)=zdufic_omp(:,:)+zdufi_omp(:,:)
720         zdvfic_omp(:,:)=zdvfic_omp(:,:)+zdvfi_omp(:,:)
721         zdtfic_omp(:,:)=zdtfic_omp(:,:)+zdtfi_omp(:,:)
722         zdqfic_omp(:,:,:)=zdqfic_omp(:,:,:)+zdqfi_omp(:,:,:)
723
724      enddo
725
726#endif
727! of #ifdef CPP_PHYS
728
729
730      zdufi_omp(:,:)=zdufic_omp(:,:)/nsplit_phys
731      zdvfi_omp(:,:)=zdvfic_omp(:,:)/nsplit_phys
732      zdtfi_omp(:,:)=zdtfic_omp(:,:)/nsplit_phys
733      zdqfi_omp(:,:,:)=zdqfic_omp(:,:,:)/nsplit_phys
734
735c$OMP BARRIER
736
737      do l=1,llm+1
738        do i=1,klon
739          zplev(offset+i,l)=zplev_omp(i,l)
740        enddo
741      enddo
742         
743       do l=1,llm
744        do i=1,klon 
745          zplay(offset+i,l)=zplay_omp(i,l)
746        enddo
747      enddo
748       
749      do l=1,llm
750        do i=1,klon
751          zphi(offset+i,l)=zphi_omp(i,l)
752        enddo
753      enddo
754       
755
756      do i=1,klon
757        zphis(offset+i)=zphis_omp(i)
758      enddo
759     
760       
761      do l=1,llm
762        presnivs(l)=presnivs_omp(l)
763      enddo
764       
765      do l=1,llm
766        do i=1,klon
767          zufi(offset+i,l)=zufi_omp(i,l)
768        enddo
769      enddo
770       
771      do l=1,llm
772        do i=1,klon
773          zvfi(offset+i,l)=zvfi_omp(i,l)
774        enddo
775      enddo
776       
777      do l=1,llm
778        do i=1,klon
779          ztfi(offset+i,l)=ztfi_omp(i,l)
780        enddo
781      enddo
782       
783      do iq=1,nqtot
784        do l=1,llm
785          do i=1,klon
786            zqfi(offset+i,l,iq)=zqfi_omp(i,l,iq)
787          enddo
788        enddo
789      enddo
790       
791      do l=1,llm
792        do i=1,klon
793          zdufi(offset+i,l)=zdufi_omp(i,l)
794        enddo
795      enddo
796       
797      do l=1,llm
798        do i=1,klon
799          zdvfi(offset+i,l)=zdvfi_omp(i,l)
800        enddo
801      enddo
802       
803      do l=1,llm
804        do i=1,klon
805          zdtfi(offset+i,l)=zdtfi_omp(i,l)
806        enddo
807      enddo
808       
809      do iq=1,nqtot
810        do l=1,llm
811          do i=1,klon
812            zdqfi(offset+i,l,iq)=zdqfi_omp(i,l,iq)
813          enddo
814        enddo
815      enddo
816       
817      do i=1,klon
818        zdpsrf(offset+i)=zdpsrf_omp(i)
819      enddo
820     
821
822      klon=klon_mpi
823500   CONTINUE
824c$OMP BARRIER
825
826c$OMP MASTER
827      call stop_timer(timer_physic)
828c$OMP END MASTER
829
830      IF (using_mpi) THEN
831           
832      if (MPI_rank>0) then
833
834c$OMP DO SCHEDULE(STATIC,OMP_CHUNK)       
835       DO l=1,llm     
836        du_send(1:iim,l)=zdufi(1:iim,l)
837        dv_send(1:iim,l)=zdvfi(1:iim,l)
838       ENDDO
839c$OMP END DO NOWAIT       
840
841c$OMP BARRIER
842#ifdef CPP_MPI
843c$OMP MASTER
844!$OMP CRITICAL (MPI)
845        call MPI_ISSEND(du_send,iim*llm,MPI_REAL8,MPI_Rank-1,401,
846     &                   COMM_LMDZ,Req(1),ierr)
847        call MPI_ISSEND(dv_send,iim*llm,MPI_REAL8,MPI_Rank-1,402,
848     &                  COMM_LMDZ,Req(2),ierr)
849!$OMP END CRITICAL (MPI)
850c$OMP END MASTER
851#endif
852c$OMP BARRIER
853     
854      endif
855   
856      if (MPI_rank<MPI_Size-1) then
857c$OMP BARRIER
858#ifdef CPP_MPI
859c$OMP MASTER     
860!$OMP CRITICAL (MPI)
861        call MPI_IRECV(du_recv,iim*llm,MPI_REAL8,MPI_Rank+1,401,
862     &                 COMM_LMDZ,Req(3),ierr)
863        call MPI_IRECV(dv_recv,iim*llm,MPI_REAL8,MPI_Rank+1,402,
864     &                 COMM_LMDZ,Req(4),ierr)
865!$OMP END CRITICAL (MPI)
866c$OMP END MASTER
867#endif
868      endif
869
870c$OMP BARRIER
871
872
873#ifdef CPP_MPI
874c$OMP MASTER   
875!$OMP CRITICAL (MPI)
876      if (MPI_rank>0 .and. MPI_rank< MPI_Size-1) then
877        call MPI_WAITALL(4,Req(1),Status,ierr)
878      else if (MPI_rank>0) then
879        call MPI_WAITALL(2,Req(1),Status,ierr)
880      else if (MPI_rank <MPI_Size-1) then
881        call MPI_WAITALL(2,Req(3),Status,ierr)
882      endif
883!$OMP END CRITICAL (MPI)
884c$OMP END MASTER
885#endif
886
887c$OMP BARRIER     
888
889      ENDIF ! using_mpi
890     
891     
892c$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
893      DO l=1,llm
894           
895        zdufi2(1:klon,l)=zdufi(1:klon,l)
896        zdufi2(klon+1:klon+iim,l)=du_recv(1:iim,l)
897           
898        zdvfi2(1:klon,l)=zdvfi(1:klon,l)
899        zdvfi2(klon+1:klon+iim,l)=dv_recv(1:iim,l)
900
901        pdhfi(:,jj_begin,l)=0
902        pdqfi(:,jj_begin,l,:)=0
903        pdufi(:,jj_begin,l)=0
904        pdvfi(:,jj_begin,l)=0
905               
906        if (.not. is_south_pole) then
907          pdhfi(:,jj_end:jj_end+1,l)=0
908          pdqfi(:,jj_end:jj_end+1,l,:)=0
909          pdufi(:,jj_end:jj_end+1,l)=0
910          pdvfi(:,jj_end:jj_end+1,l)=0
911        endif
912     
913       ENDDO
914c$OMP END DO NOWAIT
915
916c$OMP MASTER
917        pdpsfi(:,jj_begin)=0   
918       
919       if (.not. is_south_pole) then
920         pdpsfi(:,jj_end:jj_end+1)=0
921       endif
922c$OMP END MASTER
923c-----------------------------------------------------------------------
924c   transformation des tendances physiques en tendances dynamiques:
925c   ---------------------------------------------------------------
926
927c  tendance sur la pression :
928c  -----------------------------------
929c      CALL gr_fi_dyn_p(1,klon,iip1,jjp1,zdpsrf,pdpsfi)
930
931c$OMP MASTER
932      kstart=1
933      kend=klon
934
935      if (is_north_pole) kstart=2
936      if (is_south_pole)  kend=klon-1
937
938!CDIR ON_ADB(index_i)
939!CDIR ON_ADB(index_j)
940!cdir NODEP
941        do ig0=kstart,kend
942          i=index_i(ig0)
943          j=index_j(ig0)
944          pdpsfi(i,j) = zdpsrf(ig0)
945          if (i==1) pdpsfi(iip1,j) =  zdpsrf(ig0)
946         enddo         
947
948        if (is_north_pole) then
949            DO i=1,iip1
950              pdpsfi(i,1)    = zdpsrf(1)
951            enddo
952        endif
953       
954        if (is_south_pole) then
955            DO i=1,iip1
956              pdpsfi(i,jjp1) = zdpsrf(klon)
957            ENDDO
958        endif
959c$OMP END MASTER
960cc$OMP BARRIER
961
962c
963c   62. enthalpie potentielle
964c   ---------------------
965     
966      kstart=1
967      kend=klon
968
969      if (is_north_pole) kstart=2
970      if (is_south_pole)  kend=klon-1
971
972c$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
973      DO l=1,llm
974
975!CDIR ON_ADB(index_i)
976!CDIR ON_ADB(index_j)
977!cdir NODEP
978        do ig0=kstart,kend
979          i=index_i(ig0)
980          j=index_j(ig0)
981          pdhfi(i,j,l) = cpp * zdtfi(ig0,l) / ppk(i,j,l)
982          if (i==1) pdhfi(iip1,j,l) =  cpp * zdtfi(ig0,l) / ppk(i,j,l)
983         enddo         
984
985        if (is_north_pole) then
986            DO i=1,iip1
987              pdhfi(i,1,l)    = cpp *  zdtfi(1,l)      / ppk(i, 1  ,l)
988            enddo
989        endif
990       
991        if (is_south_pole) then
992            DO i=1,iip1
993              pdhfi(i,jjp1,l) = cpp *  zdtfi(klon,l)/ ppk(i,jjp1,l)
994            ENDDO
995        endif
996      ENDDO
997c$OMP END DO NOWAIT
998     
999c   62. humidite specifique
1000c   ---------------------
1001! Ehouarn: removed this useless bit: was overwritten at step 63 anyways
1002!      DO iq=1,nqtot
1003!c$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
1004!         DO l=1,llm
1005!!!cdir NODEP
1006!           do ig0=kstart,kend
1007!             i=index_i(ig0)
1008!             j=index_j(ig0)
1009!             pdqfi(i,j,l,iq) = zdqfi(ig0,l,iq)
1010!             if (i==1) pdqfi(iip1,j,l,iq) = zdqfi(ig0,l,iq)
1011!           enddo
1012!           
1013!           if (is_north_pole) then
1014!             do i=1,iip1
1015!               pdqfi(i,1,l,iq)    = zdqfi(1,l,iq)             
1016!             enddo
1017!           endif
1018!           
1019!           if (is_south_pole) then
1020!             do i=1,iip1
1021!               pdqfi(i,jjp1,l,iq) = zdqfi(klon,l,iq)
1022!             enddo
1023!           endif
1024!         ENDDO
1025!c$OMP END DO NOWAIT
1026!      ENDDO
1027
1028c   63. traceurs
1029c   ------------
1030C     initialisation des tendances
1031
1032c$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
1033      DO l=1,llm
1034        pdqfi(:,jj_begin:jj_end,l,:)=0.
1035      ENDDO
1036c$OMP END DO NOWAIT     
1037
1038C
1039!cdir NODEP
1040      DO iq=1,nqtot
1041         iiq=niadv(iq)
1042c$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
1043         DO l=1,llm
1044!CDIR ON_ADB(index_i)
1045!CDIR ON_ADB(index_j)
1046!cdir NODEP           
1047             DO ig0=kstart,kend
1048              i=index_i(ig0)
1049              j=index_j(ig0)
1050              pdqfi(i,j,l,iiq) = zdqfi(ig0,l,iq)
1051              if (i==1) pdqfi(iip1,j,l,iiq) = zdqfi(ig0,l,iq)
1052            ENDDO
1053           
1054            IF (is_north_pole) then
1055              DO i=1,iip1
1056                pdqfi(i,1,l,iiq)    = zdqfi(1,l,iq)
1057              ENDDO
1058            ENDIF
1059           
1060            IF (is_south_pole) then
1061              DO i=1,iip1
1062                pdqfi(i,jjp1,l,iiq) = zdqfi(klon,l,iq)
1063              ENDDO
1064            ENDIF
1065           
1066         ENDDO
1067c$OMP END DO NOWAIT     
1068      ENDDO
1069     
1070c   65. champ u:
1071c   ------------
1072c$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
1073      DO l=1,llm
1074!CDIR ON_ADB(index_i)
1075!CDIR ON_ADB(index_j)
1076!cdir NODEP
1077         do ig0=kstart,kend
1078           i=index_i(ig0)
1079           j=index_j(ig0)
1080           
1081           if (i/=iim) then
1082             pdufi(i,j,l)=0.5*(zdufi2(ig0,l)+zdufi2(ig0+1,l))*cu(i,j)
1083           endif
1084           
1085           if (i==1) then
1086              pdufi(iim,j,l)=0.5*(  zdufi2(ig0,l)
1087     $                            + zdufi2(ig0+iim-1,l))*cu(iim,j)
1088             pdufi(iip1,j,l)=0.5*(zdufi2(ig0,l)+zdufi2(ig0+1,l))*cu(i,j)
1089           endif
1090         
1091         enddo
1092         
1093         if (is_north_pole) then
1094           DO i=1,iip1
1095            pdufi(i,1,l)    = 0.
1096           ENDDO
1097         endif
1098         
1099         if (is_south_pole) then
1100           DO i=1,iip1
1101            pdufi(i,jjp1,l) = 0.
1102           ENDDO
1103         endif
1104         
1105      ENDDO
1106c$OMP END DO NOWAIT
1107
1108c   67. champ v:
1109c   ------------
1110
1111      kstart=1
1112      kend=klon
1113
1114      if (is_north_pole) kstart=2
1115      if (is_south_pole)  kend=klon-1-iim
1116     
1117c$OMP DO SCHEDULE(STATIC,OMP_CHUNK)     
1118      DO l=1,llm
1119!CDIR ON_ADB(index_i)
1120!CDIR ON_ADB(index_j)
1121!cdir NODEP
1122        do ig0=kstart,kend
1123           i=index_i(ig0)
1124           j=index_j(ig0)
1125           pdvfi(i,j,l)=0.5*(zdvfi2(ig0,l)+zdvfi2(ig0+iim,l))*cv(i,j)
1126           if (i==1) pdvfi(iip1,j,l) = 0.5*(zdvfi2(ig0,l)+
1127     $                                      zdvfi2(ig0+iim,l))
1128     $                                    *cv(i,j)
1129        enddo
1130         
1131      ENDDO
1132c$OMP END DO NOWAIT
1133
1134
1135c   68. champ v pres des poles:
1136c   ---------------------------
1137c      v = U * cos(long) + V * SIN(long)
1138
1139      if (is_north_pole) then
1140
1141c$OMP DO SCHEDULE(STATIC,OMP_CHUNK)     
1142        DO l=1,llm
1143
1144          DO i=1,iim
1145            pdvfi(i,1,l)=
1146     $      zdufi(1,l)*COS(rlonv(i))+zdvfi(1,l)*SIN(rlonv(i))
1147       
1148            pdvfi(i,1,l)=
1149     $      0.5*(pdvfi(i,1,l)+zdvfi(i+1,l))*cv(i,1)
1150          ENDDO
1151
1152          pdvfi(iip1,1,l)  = pdvfi(1,1,l)
1153
1154        ENDDO
1155c$OMP END DO NOWAIT
1156
1157      endif   
1158     
1159      if (is_south_pole) then
1160
1161c$OMP DO SCHEDULE(STATIC,OMP_CHUNK)     
1162         DO l=1,llm
1163 
1164           DO i=1,iim
1165              pdvfi(i,jjm,l)=zdufi(klon,l)*COS(rlonv(i))
1166     $        +zdvfi(klon,l)*SIN(rlonv(i))
1167
1168              pdvfi(i,jjm,l)=
1169     $        0.5*(pdvfi(i,jjm,l)+zdvfi(klon-iip1+i,l))*cv(i,jjm)
1170           ENDDO
1171
1172           pdvfi(iip1,jjm,l)= pdvfi(1,jjm,l)
1173
1174        ENDDO
1175c$OMP END DO NOWAIT
1176     
1177      endif
1178c-----------------------------------------------------------------------
1179
1180700   CONTINUE
1181 
1182      firstcal = .FALSE.
1183
1184#else
1185      write(lunout,*)
1186     & "calfis_p: for now can only work with parallel physics"
1187      stop
1188#endif
1189! of #ifdef CPP_PHYS
1190#endif
1191! of #ifdef CPP_PARA
1192      END
Note: See TracBrowser for help on using the repository browser.