source: LMDZ6/trunk/libf/dyn3dmem/advtrac_loc.f90

Last change on this file was 5272, checked in by abarral, 27 hours ago

Turn paramet.h into a module

  • Property copyright set to
    Name of program: LMDZ
    Creation date: 1984
    Version: LMDZ5
    License: CeCILL version 2
    Holder: Laboratoire de m\'et\'eorologie dynamique, CNRS, UMR 8539
    See the license file in the root directory
File size: 12.9 KB
Line 
1
2SUBROUTINE advtrac_loc(pbarug, pbarvg, wg, p, massem, q, teta, pk)
3   !     Auteur :  F. Hourdin
4   !
5   !     Modif. P. Le Van     (20/12/97)
6   !            F. Codron     (10/99)
7   !            D. Le Croller (07/2001)
8   !            M.A Filiberti (04/2002)
9   !
10   USE infotrac,     ONLY: nqtot, tracers
11   USE control_mod,  ONLY: iapp_tracvl, day_step, planet_type
12   USE comconst_mod, ONLY: dtvr
13   USE parallel_lmdz
14   USE Write_Field_loc
15   USE Write_Field
16   USE Bands
17   USE mod_hallo
18   USE Vampir
19   USE times
20   USE advtrac_mod, ONLY: finmasse
21   USE lmdz_cppkeys_wrapper, ONLY: CPPKEY_DEBUGIO
22   USE strings_mod, ONLY: int2str
23   USE dimensions_mod, ONLY: iim, jjm, llm, ndm
24USE paramet_mod_h, ONLY: iip1, iip2, iip3, jjp1, llmp1, llmp2, llmm1, kftd, ip1jm, ip1jmp1, &
25          ip1jmi1, ijp1llm, ijmllm, mvar, jcfil, jcfllm
26IMPLICIT NONE
27   !
28
29
30   include "comdissip.h"
31   include "comgeom2.h"
32   include "description.h"
33!   include "iniprint.h"
34
35   !---------------------------------------------------------------------------
36   !     Arguments
37   !---------------------------------------------------------------------------
38   REAL, INTENT(IN) ::  pbarug(ijb_u:ije_u,llm)
39   REAL, INTENT(IN) ::  pbarvg(ijb_v:ije_v,llm)
40   REAL, INTENT(IN) ::      wg(ijb_u:ije_u,llm)
41   REAL, INTENT(IN) ::       p(ijb_u:ije_u,llmp1)
42   REAL, INTENT(IN) ::  massem(ijb_u:ije_u,llm)
43   REAL, INTENT(INOUT) ::    q(ijb_u:ije_u,llm,nqtot)
44   REAL, INTENT(IN) ::    teta(ijb_u:ije_u,llm)
45   REAL, INTENT(IN) ::      pk(ijb_u:ije_u,llm)
46   !---------------------------------------------------------------------------
47   !     Ajout PPM
48   !---------------------------------------------------------------------------
49   REAL :: massebx(ijb_u:ije_u,llm), masseby(ijb_v:ije_v,llm)
50   !---------------------------------------------------------------------------
51   !     Variables locales
52   !---------------------------------------------------------------------------
53   INTEGER :: ij, l, iq, iadv
54   REAL(KIND=KIND(1.d0)) :: t_initial, t_final, tps_cpu
55   REAL :: zdp(ijb_u:ije_u), zdpmin, zdpmax
56   INTEGER, SAVE :: iadvtr=0
57!$OMP THREADPRIVATE(iadvtr)
58   EXTERNAL  minmax
59
60   !---------------------------------------------------------------------------
61   !     Rajouts pour PPM
62   !---------------------------------------------------------------------------
63   INTEGER :: indice, n
64   REAL :: dtbon                       ! Pas de temps adaptatif pour que CFL<1
65   REAL :: CFLmaxz, aaa, bbb           ! CFL maximum
66   REAL, DIMENSION(iim,jjb_u:jje_u,llm) :: unatppm, vnatppm, fluxwppm
67   REAL ::    qppm(iim*jjnb_u,llm,nqtot)
68   REAL ::   psppm(iim,jjb_u:jje_u)    ! pression  au sol
69   REAL, DIMENSION(llmp1) :: apppm, bpppm
70   LOGICAL, SAVE :: dum=.TRUE., fill=.TRUE.
71   INTEGER :: ijb, ije, ijbu, ijbv, ijeu, ijev, j
72   TYPE(Request),SAVE :: testRequest
73!$OMP THREADPRIVATE(testRequest)
74
75! Test sur l'eventuelle creation de valeurs negatives de la masse
76   ijb = ij_begin; IF(pole_nord) ijb = ij_begin+iip1
77   ije = ij_end;   IF(pole_sud)  ije = ij_end-iip1
78
79!$OMP DO SCHEDULE(STATIC,OMP_CHUNK)
80   DO l=1,llm-1
81      DO ij = ijb+1,ije
82         zdp(ij) = pbarug(ij-1,l)    - pbarug(ij,l) &
83                 - pbarvg(ij-iip1,l) + pbarvg(ij,l) &
84                 +     wg(ij,l+1)    -     wg(ij,l)
85      END DO
86! ym  ---> pourquoi jjm-1 et non jjm ? a cause du pole ?
87!     CALL SCOPY( jjm -1 ,zdp(iip1+iip1),iip1,zdp(iip2),iip1 )
88      DO ij = ijb,ije-iip1+1,iip1
89         zdp(ij)=zdp(ij+iip1-1)
90      END DO
91      DO ij = ijb,ije
92         zdp(ij)= zdp(ij)*dtvr/ massem(ij,l)
93      END DO
94!     CALL minmax ( ip1jm-iip1, zdp(iip2), zdpmin,zdpmax )
95! ym ---> eventuellement a revoir
96      CALL minmax( ije-ijb+1, zdp(ijb), zdpmin,zdpmax )
97      IF(MAX(ABS(zdpmin),ABS(zdpmax)) >0.5) &
98         WRITE(*,*)'WARNING DP/P l=',l,'  MIN:',zdpmin,'   MAX:', zdpmax
99   END DO
100!$OMP END DO NOWAIT
101
102   !---------------------------------------------------------------------------
103   !   Advection proprement dite (Modification Le Croller (07/2001)
104   !---------------------------------------------------------------------------
105
106   !---------------------------------------------------------------------------
107   !   Calcul des moyennes basees sur la masse
108   !---------------------------------------------------------------------------
109!ym   CALL massbar_p(massem,massebx,masseby)
110!ym   ----> Normalement, inutile pour les schemas classiques
111!ym   ----> Reverifier lors de la parallelisation des autres schemas
112
113IF (CPPKEY_DEBUGIO) THEN
114   CALL WriteField_u('massem',massem)
115   CALL WriteField_u('wg',wg)
116   CALL WriteField_u('pbarug',pbarug)
117   CALL WriteField_v('pbarvg',pbarvg)
118   CALL WriteField_u('p_tmp',p)
119   CALL WriteField_u('pk_tmp',pk)
120   CALL WriteField_u('teta_tmp',teta)
121   DO iq=1,nqtot
122      CALL WriteField_u('q_adv'//trim(int2str(iq)),q(:,:,iq))
123   END DO
124END IF
125
126!         
127!  CALL Register_Hallo_v(pbarvg,llm,1,1,1,1,TestRequest)
128!  CALL SendRequest(TestRequest)
129!!$OMP BARRIER
130!  CALL WaitRequest(TestRequest)
131!$OMP BARRIER
132
133!  WRITE(*,*) 'advtrac 157: appel de vlspltgen_loc'
134   CALL vlspltgen_loc(q, 2., massem, wg, pbarug, pbarvg, dtvr, p, pk, teta )
135
136IF (CPPKEY_DEBUGIO) THEN
137   DO iq = 1, nqtot
138      CALL WriteField_u('q_adv'//trim(int2str(iq)),q(:,:,iq))
139   END DO
140END IF
141         
142   GOTO 1234     
143   !-------------------------------------------------------------------------
144   !       Appel des sous programmes d'advection
145   !-------------------------------------------------------------------------
146   DO iq = 1, nqtot
147!     CALL clock(t_initial)
148      IF(tracers(iq)%parent /= 'air') CYCLE
149      iadv = tracers(iq)%iadv
150      !-----------------------------------------------------------------------
151      SELECT CASE(iadv)
152      !-----------------------------------------------------------------------
153         CASE(0); CYCLE
154         !--------------------------------------------------------------------
155         CASE(10)  !--- Schema de Van Leer I MUSCL
156         !--------------------------------------------------------------------
157!           WRITE(*,*) 'advtrac 239: iq,q(1721,19,:)=',iq,q(1721,19,:)     
158!LF         CALL vlsplt_p(q(1,1,iq),2.,massem,wg,pbarug,pbarvg,dtvr)
159
160         !--------------------------------------------------------------------
161         CASE(14)  !--- Schema "pseuDO amont" + test sur humidite specifique
162                   !--- pour la vapeur d'eau. F. Codron
163         !--------------------------------------------------------------------
164!           WRITE(*,*) 'advtrac 248: iq,q(1721,19,:)=',iq,q(1721,19,:)
165            CALL abort_gcm("advtrac","appel a vlspltqs :schema non parallelise",1)
166!LF         CALL vlspltqs_p(q(1,1,1),2.,massem,wg,pbarug,pbarvg,dtvr,p,pk,teta )
167
168         !--------------------------------------------------------------------
169         CASE(12)  !--- Schema de Frederic Hourdin
170         !--------------------------------------------------------------------
171            CALL abort_gcm("advtrac","appel a vlspltqs :schema non parallelise",1)
172            CALL adaptdt(iadv,dtbon,n,pbarug,massem)   ! pas de temps adaptatif
173            IF(n > 1) WRITE(*,*) 'WARNING horizontal dt=',dtbon,'dtvr=',dtvr,'n=',n
174            DO indice=1,n
175              CALL advn(q(1,1,iq),massem,wg,pbarug,pbarvg,dtbon,1)
176            END DO
177
178         !--------------------------------------------------------------------
179         CASE(13)  !--- Pas de temps adaptatif
180         !--------------------------------------------------------------------
181            CALL abort_gcm("advtrac","schema non parallelise",1)
182            CALL adaptdt(iadv,dtbon,n,pbarug,massem)
183            IF(n > 1) WRITE(*,*) 'WARNING horizontal dt=',dtbon,'dtvr=',dtvr,'n=',n
184            DO indice=1,n
185               CALL advn(q(1,1,iq),massem,wg,pbarug,pbarvg,dtbon,2)
186            END DO
187
188         !--------------------------------------------------------------------
189         CASE(20)  !--- Schema de pente SLOPES
190         !--------------------------------------------------------------------
191            CALL abort_gcm("advtrac","schema SLOPES non parallelise",1)
192            CALL pentes_ini (q(1,1,iq),wg,massem,pbarug,pbarvg,0)
193
194         !--------------------------------------------------------------------
195         CASE(30)  !--- Schema de Prather
196         !--------------------------------------------------------------------
197            CALL abort_gcm("advtrac","schema prather non parallelise",1)
198            ! Pas de temps adaptatif
199            CALL adaptdt(iadv,dtbon,n,pbarug,massem)
200            IF(n > 1) WRITE(*,*) 'WARNING horizontal dt=',dtbon,'dtvr=',dtvr,'n=',n
201            CALL prather(q(1,1,iq),wg,massem,pbarug,pbarvg,n,dtbon)
202
203         !--------------------------------------------------------------------
204         CASE(11,16,17,18)   !--- Schemas PPM Lin et Rood
205         !--------------------------------------------------------------------
206            CALL abort_gcm("advtrac","schema PPM non parallelise",1)
207            ! Test sur le flux horizontal
208            CALL adaptdt(iadv,dtbon,n,pbarug,massem)   ! pas de temps adaptatif
209            IF(n > 1) WRITE(*,*) 'WARNING horizontal dt=',dtbon,'dtvr=',dtvr,'n=',n
210            ! Test sur le flux vertical
211            CFLmaxz=0.
212            DO l=2,llm
213               DO ij=iip2,ip1jm
214                  aaa=wg(ij,l)*dtvr/massem(ij,l)
215                  CFLmaxz=max(CFLmaxz,aaa)
216                  bbb=-wg(ij,l)*dtvr/massem(ij,l-1)
217                  CFLmaxz=max(CFLmaxz,bbb)
218               END DO
219            END DO
220            IF(CFLmaxz.GE.1) WRITE(*,*) 'WARNING vertical','CFLmaxz=', CFLmaxz
221            !----------------------------------------------------------------
222            !     Ss-prg interface LMDZ.4->PPM3d (ss-prg de Lin)
223            !----------------------------------------------------------------
224            CALL interpre(q(1,1,iq),qppm(1,1,iq),wg,fluxwppm,massem, &
225                 apppm,bpppm,massebx,masseby,pbarug,pbarvg, &
226                 unatppm,vnatppm,psppm)
227
228            !----------------------------------------------------------------
229            DO indice=1,n     !--- VL (version PPM) horiz. et PPM vert.
230            !----------------------------------------------------------------
231               SELECT CASE(iadv)
232                  !----------------------------------------------------------
233                  CASE(11)
234                  !----------------------------------------------------------
235                     CALL ppm3d(1,qppm(1,1,iq),psppm,psppm,unatppm,vnatppm,fluxwppm,dtbon, &
236                                2,2,2,1,iim,jjp1,2,llm,apppm,bpppm,0.01,6400000,fill,dum,220.)
237                  !----------------------------------------------------------
238                  CASE(16) !--- Monotonic PPM
239                  !----------------------------------------------------------
240                     CALL ppm3d(1,qppm(1,1,iq),psppm,psppm,unatppm,vnatppm,fluxwppm,dtbon, &
241                                3,3,3,1,iim,jjp1,2,llm,apppm,bpppm,0.01,6400000,fill,dum,220.)
242                  !----------------------------------------------------------
243                  CASE(17) !--- Semi monotonic PPM
244                  !----------------------------------------------------------
245                     CALL ppm3d(1,qppm(1,1,iq),psppm,psppm,unatppm,vnatppm,fluxwppm,dtbon, &
246                                4,4,4,1,iim,jjp1,2,llm,apppm,bpppm,0.01,6400000, fill,dum,220.)
247                  !----------------------------------------------------------
248                  CASE(18) !--- Positive Definite PPM
249                  !----------------------------------------------------------
250                     CALL ppm3d(1,qppm(1,1,iq),psppm,psppm,unatppm,vnatppm,fluxwppm,dtbon, &
251                                5,5,5,1,iim,jjp1,2,llm,apppm,bpppm,0.01,6400000,fill,dum,220.)
252               END SELECT
253            !----------------------------------------------------------------
254            END DO
255            !----------------------------------------------------------------
256            !     Ss-prg interface PPM3d-LMDZ.4
257            !----------------------------------------------------------------
258            CALL interpost(q(1,1,iq),qppm(1,1,iq))
259      !----------------------------------------------------------------------
260      END SELECT
261      !----------------------------------------------------------------------
262
263      !----------------------------------------------------------------------
264      ! On impose une seule valeur du traceur au pole Sud j=jjm+1=jjp1 et Nord j=1
265      !----------------------------------------------------------------------
266      !  CALL traceurpole(q(1,1,iq),massem)
267
268      !--- Calcul du temps cpu pour un schema donne
269      !  CALL clock(t_final)
270      !ym  tps_cpu=t_final-t_initial
271      !ym  cpuadv(iq)=cpuadv(iq)+tps_cpu
272
273   END DO
274
2751234 CONTINUE
276!$OMP BARRIER
277   IF(planet_type=="earth") THEN
278      ijb=ij_begin
279      ije=ij_end
280!$OMP DO SCHEDULE(STATIC,OMP_CHUNK)     
281      DO l = 1, llm
282         DO ij = ijb, ije
283            finmasse(ij,l) =  p(ij,l) - p(ij,l+1)
284         END DO
285      END DO
286!$OMP END DO
287
288      CALL qminimum_loc( q, nqtot, finmasse )
289
290   END IF ! of if (planet_type=="earth")
291
292END SUBROUTINE advtrac_loc
293
Note: See TracBrowser for help on using the repository browser.