Newer
Older

ESCOBAR MUNOZ Juan
committed
!MNH_LIC Copyright 1994-2020 CNRS, Meteo-France and Universite Paul Sabatier
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
!MNH_LIC This is part of the Meso-NH software governed by the CeCILL-C licence
!MNH_LIC version 1. See LICENSE, CeCILL-C_V1-en.txt and CeCILL-C_V1-fr.txt
!MNH_LIC for details. version 1.
!-----------------------------------------------------------------
! Modifications:
! P. Wautelet 05/2016-04/2018: new data structures and calls for I/O
! P. Wautelet 20/06/2019: OpenACC: correct intent of some dummy variables
! P. Wautelet 01/07/2019: OpenACC: optimisation of ppm_s0_x/y/z_d for GPU
! P. Wautelet 18/07/2019: OpenACC: remove use of macros for dif2x/y/z
!-----------------------------------------------------------------
#ifdef MNH_OPENACC
!
! inline shuman with macro
!
!#define dxf(PDXF,PA) PDXF(1:IIU-1,:,:) = PA(2:IIU,:,:) - PA(1:IIU-1,:,:) ; PDXF(IIU,:,:) = PDXF(2*JPHEXT,:,:) ! DXF(PDXF,PA)
!#define dyf(PDYF,PA) PDYF(:,1:IJU-1,:) = PA(:,2:IJU,:) - PA(:,1:IJU-1,:); PDYF(:,IJU,:) = PDYF(:,2*JPHEXT,:) ! DYF(PDYF,PA)
!!#define dyf(PDYF,PA) PDYF(1:IIU,1:IJU-1,IKB:IKE) = PA(1:IIU,2:IJU,IKB:IKE) - PA(1:IIU,1:IJU-1,IKB:IKE); ! PDYF(1:IIU,IJU,IKB:IKE) = PDYF(1:IIU,2*JPHEXT,IKB:IKE) ! DYF(PDYF,PA)
!#define dzf(PDZF,PA) PDZF(:,:,1:IKU-1) = PA(:,:,2:IKU) - PA(:,:,1:IKU-1) ; PDZF(:,:,IKU) = -999. ! DZF(PDZF,PA)
!
!#define mxm(PMXM,PA) PMXM(2:IIU,:,:) = 0.5*( PA(2:IIU,:,:)+PA(1:IIU-1,:,:) ) ; PMXM(1,:,:) = PMXM(IIU-2*JPHEXT+1,:,:) ! MXM(PMXM,PA)
!!#define mym(PMYM,PA) PMYM(1:IIU,2:IJU,IKB:IKE) = 0.5*( PA(1:IIU,2:IJU,IKB:IKE)+PA(1:IIU,1:IJU-1,IKB:IKE) ) ; ! PMYM(1:IIU,1,IKB:IKE) = PMYM(1:IIU,IJU-2*JPHEXT+1,IKB:IKE) ! MYM(PMYM,PA)
!#define mzm(PMZM,PA) PMZM(:,:,2:IKU) = 0.5*( PA(:,:,2:IKU)+PA(:,:,1:IKU-1) ) ; PMZM(:,:,1) = -999. ! MZM(PMZM,PA)
!#define mym(PMYM,PA) PMYM(:,2:IJU,:) = 0.5*( PA(:,2:IJU,:)+PA(:,1:IJU-1,:) ) ; PMYM(:,1,:) = PMYM(:,IJU-2*JPHEXT+1,:) ! MYM(PMYM,PA)
!
! #define dif2x(DQ,PQ) DQ(IIB:IIE,:,:)=0.5*(PQ(IIB+1:IIE+1,:,:)-PQ(IIB-1:IIE-1,:,:));\
! DQ(IIB-1,:,:)=0.5*(PQ(IIB,:,:)-PQ(IIE-1,:,:));\
! DQ(IIE+1,:,:)=0.5*(PQ(IIB+1,:,:)-PQ(IIE,:,:)) ! DIF2X(DQ,PQ)
!
! #define dif2y(DQ,PQ) DQ(1:IIU,IJB:IJE,IKB:IKE) = 0.5*(PQ(1:IIU,IJB+1:IJE+1,IKB:IKE) - PQ(1:IIU,IJB-1:IJE-1,IKB:IKE)) ; !
! ! DQ(1:IIU,IJB-1,IKB:IKE) = 0.5*(PQ(1:IIU,IJB,IKB:IKE) - PQ(1:IIU,IJE-1,IKB:IKE)) ; \
! DQ(1:IIU,IJE+1,IKB:IKE) = 0.5*(PQ(1:IIU,IJB+1,IKB:IKE) - PQ(1:IIU,IJE,IKB:IKE)) ! DIF2Y(DQ,PQ)
!
! #define dif2z(DQ,PQ) DQ(:,:,IKB:IKE) = 0.5*(PQ(:,:,IKB+1:IKE+1) - PQ(:,:,IKB-1:IKE-1)) ; \
! DQ(:,:,IKB-1) = -DQ(:,:,IKB) ;\
! DQ(:,:,IKE+1) = -DQ(:,:,IKE) ! DIF2Z(DQ,PQ)
!
#endif
! ###############
MODULE MODI_PPM
! ###############
!
INTERFACE
!
#ifndef MNH_OPENACC
FUNCTION PPM_01_X(HLBCX, KGRID, PSRC, PCR, PRHO, PTSTEP) &
RESULT(PR)
#else
SUBROUTINE PPM_01_X(HLBCX, KGRID, PSRC, PCR, PRHO, PTSTEP, PR)
#endif
CHARACTER (LEN=4), DIMENSION(2), INTENT(IN) :: HLBCX ! X direction LBC type
!
INTEGER, INTENT(IN) :: KGRID ! C grid localisation
!
REAL, DIMENSION(:,:,:), INTENT(INOUT) :: PSRC ! variable at t
REAL, DIMENSION(:,:,:), INTENT(IN) :: PCR ! Courant number
REAL, DIMENSION(:,:,:), INTENT(IN) :: PRHO ! density
REAL, INTENT(IN) :: PTSTEP ! Time step
!
! output source term
#ifndef MNH_OPENACC
REAL, DIMENSION(SIZE(PCR,1),SIZE(PCR,2),SIZE(PCR,3)) :: PR
#else
REAL, DIMENSION(:,:,:), INTENT(OUT) :: PR
#endif
!
#ifndef MNH_OPENACC
END FUNCTION PPM_01_X
#else
END SUBROUTINE PPM_01_X
#endif
!
!
#ifndef MNH_OPENACC
FUNCTION PPM_01_Y(HLBCY, KGRID, PSRC, PCR, PRHO, PTSTEP) &
RESULT(PR)
#else
SUBROUTINE PPM_01_Y(HLBCY, KGRID, PSRC, PCR, PRHO, PTSTEP, PR)
#endif
CHARACTER (LEN=4), DIMENSION(2), INTENT(IN) :: HLBCY ! Y direction LBC type
!
INTEGER, INTENT(IN) :: KGRID ! C grid localisation
!
REAL, DIMENSION(:,:,:), INTENT(INOUT) :: PSRC ! variable at t
REAL, DIMENSION(:,:,:), INTENT(IN) :: PCR ! Courant number
REAL, DIMENSION(:,:,:), INTENT(IN) :: PRHO ! density
REAL, INTENT(IN) :: PTSTEP ! Time step
!
! output source term
#ifndef MNH_OPENACC
REAL, DIMENSION(SIZE(PCR,1),SIZE(PCR,2),SIZE(PCR,3)) :: PR
#else
REAL, DIMENSION(:,:,:), INTENT(OUT) :: PR
#endif
!
#ifndef MNH_OPENACC
END FUNCTION PPM_01_Y
#else
END SUBROUTINE PPM_01_Y
#endif
!
#ifndef MNH_OPENACC
FUNCTION PPM_01_Z(KGRID, PSRC, PCR, PRHO, PTSTEP) RESULT(PR)
#else
SUBROUTINE PPM_01_Z(KGRID, PSRC, PCR, PRHO, PTSTEP, PR)
#endif
!
INTEGER, INTENT(IN) :: KGRID ! C grid localisation
!
#ifndef MNH_OPENACC
REAL, DIMENSION(:,:,:), INTENT(IN) :: PSRC ! variable at t
#else
REAL, DIMENSION(:,:,:), INTENT(INOUT) :: PSRC ! variable at t
#endif
REAL, DIMENSION(:,:,:), INTENT(IN) :: PCR ! Courant number
REAL, DIMENSION(:,:,:), INTENT(IN) :: PRHO ! density
REAL, INTENT(IN) :: PTSTEP ! Time step
!
! output source term
#ifndef MNH_OPENACC
REAL, DIMENSION(SIZE(PCR,1),SIZE(PCR,2),SIZE(PCR,3)) :: PR
#else
REAL, DIMENSION(:,:,:), INTENT(OUT) :: PR
#endif
!
#ifndef MNH_OPENACC
END FUNCTION PPM_01_Z
#else
END SUBROUTINE PPM_01_Z
#endif
!
#ifndef MNH_OPENACC
FUNCTION PPM_S0_X(HLBCX, KGRID, PSRC, PCR, PRHO, PTSTEP) &
RESULT(PR)
#else
SUBROUTINE PPM_S0_X(HLBCX, KGRID, PSRC, PCR, PRHO, PTSTEP &
, PR)
#endif
CHARACTER (LEN=4), DIMENSION(2), INTENT(IN) :: HLBCX ! X direction LBC type
!
INTEGER, INTENT(IN) :: KGRID ! C grid localisation
!
REAL, DIMENSION(:,:,:), INTENT(INOUT) :: PSRC ! variable at t
REAL, DIMENSION(:,:,:), INTENT(IN) :: PCR ! Courant number
REAL, DIMENSION(:,:,:), INTENT(IN) :: PRHO ! density
REAL, INTENT(IN) :: PTSTEP ! Time step
!
! output source term
#ifndef MNH_OPENACC
REAL, DIMENSION(SIZE(PCR,1),SIZE(PCR,2),SIZE(PCR,3)) :: PR
#else
REAL, DIMENSION(:,:,:), INTENT(OUT) :: PR
#endif
!
#ifndef MNH_OPENACC
END FUNCTION PPM_S0_X
#else
END SUBROUTINE PPM_S0_X
#endif
!
#ifndef MNH_OPENACC
FUNCTION PPM_S0_Y(HLBCY, KGRID, PSRC, PCR, PRHO, PTSTEP) &
RESULT(PR)
#else
SUBROUTINE PPM_S0_Y(HLBCY, KGRID, PSRC, PCR, PRHO, PTSTEP &
, PR)
#endif
!
CHARACTER (LEN=4), DIMENSION(2), INTENT(IN) :: HLBCY ! Y direction LBC type
!
INTEGER, INTENT(IN) :: KGRID ! C grid localisation
!
REAL, DIMENSION(:,:,:), INTENT(INOUT) :: PSRC ! variable at t
REAL, DIMENSION(:,:,:), INTENT(IN) :: PCR ! Courant number
!
REAL, DIMENSION(:,:,:), INTENT(IN) :: PRHO ! density
REAL, INTENT(IN) :: PTSTEP ! Time step
!
! output source term
#ifndef MNH_OPENACC
REAL, DIMENSION(SIZE(PCR,1),SIZE(PCR,2),SIZE(PCR,3)) :: PR
#else
REAL, DIMENSION(:,:,:), INTENT(OUT) :: PR
#endif
!
#ifndef MNH_OPENACC
END FUNCTION PPM_S0_Y
#else
END SUBROUTINE PPM_S0_Y
#endif
!
#ifndef MNH_OPENACC
FUNCTION PPM_S0_Z(KGRID, PSRC, PCR, PRHO, PTSTEP) &
RESULT(PR)
#else
SUBROUTINE PPM_S0_Z(KGRID, PSRC, PCR, PRHO, PTSTEP &
, PR)
#endif
!
INTEGER, INTENT(IN) :: KGRID ! C grid localisation
!
REAL, DIMENSION(:,:,:), INTENT(INOUT) :: PSRC ! variable at t
REAL, DIMENSION(:,:,:), INTENT(IN) :: PCR ! Courant number
REAL, DIMENSION(:,:,:), INTENT(IN) :: PRHO ! density
REAL, INTENT(IN) :: PTSTEP ! Time step
!
! output source term
#ifndef MNH_OPENACC
REAL, DIMENSION(SIZE(PCR,1),SIZE(PCR,2),SIZE(PCR,3)) :: PR
#else
REAL, DIMENSION(:,:,:), INTENT(OUT) :: PR
#endif
!
#ifndef MNH_OPENACC
END FUNCTION PPM_S0_Z
#else
END SUBROUTINE PPM_S0_Z
#endif
!
#ifndef MNH_OPENACC
FUNCTION PPM_S1_X(HLBCX, KGRID, PSRC, PCR, PRHO, PRHOT, &
PTSTEP) RESULT(PR)
#else
SUBROUTINE PPM_S1_X(HLBCX, KGRID, PSRC, PCR, PRHO, PRHOT, &
PTSTEP, PR)
#endif
!
CHARACTER (LEN=4), DIMENSION(2), INTENT(IN) :: HLBCX ! X direction LBC type
!
INTEGER, INTENT(IN) :: KGRID ! C grid localisation
!
REAL, DIMENSION(:,:,:), INTENT(INOUT) :: PSRC ! variable at t
REAL, DIMENSION(:,:,:), INTENT(IN) :: PCR ! Courant number
REAL, DIMENSION(:,:,:), INTENT(IN) :: PRHO ! density
REAL, DIMENSION(:,:,:), INTENT(IN) :: PRHOT ! density at t+dt
REAL, INTENT(IN) :: PTSTEP ! Time step
!
! output source term
#ifndef MNH_OPENACC
REAL, DIMENSION(SIZE(PCR,1),SIZE(PCR,2),SIZE(PCR,3)) :: PR
#else
REAL, DIMENSION(:,:,:), INTENT(OUT) :: PR
#endif
!
#ifndef MNH_OPENACC
END FUNCTION PPM_S1_X
#else
END SUBROUTINE PPM_S1_X
#endif
!
#ifndef MNH_OPENACC
FUNCTION PPM_S1_Y(HLBCY, KGRID, PSRC, PCR, PRHO, PRHOT, &
PTSTEP) RESULT(PR)
#else
SUBROUTINE PPM_S1_Y(HLBCY, KGRID, PSRC, PCR, PRHO, PRHOT, &
PTSTEP, PR)
#endif
!
CHARACTER (LEN=4), DIMENSION(2), INTENT(IN) :: HLBCY ! X direction LBC type
!
INTEGER, INTENT(IN) :: KGRID ! C grid localisation
!
REAL, DIMENSION(:,:,:), INTENT(INOUT) :: PSRC ! variable at t
REAL, DIMENSION(:,:,:), INTENT(IN) :: PCR ! Courant number
REAL, DIMENSION(:,:,:), INTENT(IN) :: PRHO ! density
REAL, DIMENSION(:,:,:), INTENT(IN) :: PRHOT ! density at t+dt
REAL, INTENT(IN) :: PTSTEP ! Time step
!
! output source term
#ifndef MNH_OPENACC
REAL, DIMENSION(SIZE(PCR,1),SIZE(PCR,2),SIZE(PCR,3)) :: PR
#else
REAL, DIMENSION(:,:,:), INTENT(OUT) :: PR
#endif
!
#ifndef MNH_OPENACC
END FUNCTION PPM_S1_Y
#else
END SUBROUTINE PPM_S1_Y
#endif
!
#ifndef MNH_OPENACC
FUNCTION PPM_S1_Z(KGRID, PSRC, PCR, PRHO, PRHOT, PTSTEP) &
RESULT(PR)
#else
SUBROUTINE PPM_S1_Z(KGRID, PSRC, PCR, PRHO, PRHOT, PTSTEP, &
PR)
#endif
!
INTEGER, INTENT(IN) :: KGRID ! C grid localisation
!
#ifndef MNH_OPENACC
REAL, DIMENSION(:,:,:), INTENT(IN) :: PSRC ! variable at t
#else
REAL, DIMENSION(:,:,:), INTENT(INOUT) :: PSRC ! variable at t
#endif
REAL, DIMENSION(:,:,:), INTENT(IN) :: PCR ! Courant number
REAL, DIMENSION(:,:,:), INTENT(IN) :: PRHO ! density
REAL, DIMENSION(:,:,:), INTENT(IN) :: PRHOT ! density at t+dt
REAL, INTENT(IN) :: PTSTEP ! Time step
!
! output source term
#ifndef MNH_OPENACC
REAL, DIMENSION(SIZE(PCR,1),SIZE(PCR,2),SIZE(PCR,3)) :: PR
#else
REAL, DIMENSION(:,:,:), INTENT(OUT) :: PR
#endif
!
#ifndef MNH_OPENACC
END FUNCTION PPM_S1_Z
#else
END SUBROUTINE PPM_S1_Z
#endif
!
END INTERFACE
!
END MODULE MODI_PPM
!
!
!-------------------------------------------------------------------------------
!
#ifdef MNH_OPENACC

ESCOBAR MUNOZ Juan
committed
! ########################################################################
!!$ FUNCTION PPM_01_X(HLBCX, KGRID, PSRC, PCR, PRHO, PTSTEP) &
!!$ RESULT(PR)
SUBROUTINE PPM_01_X(HLBCX, KGRID, PSRC, PCR, PRHO, PTSTEP, PR)

ESCOBAR MUNOZ Juan
committed
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
! ########################################################################
USE MODE_MNH_ZWORK, ONLY : ZT3D, MNH_GET_ZT3D , MNH_REL_ZT3D
USE MODE_MNH_ZWORK, ONLY : IIU,IJU,IKU
IMPLICIT NONE
!
!* 0.1 Declarations of dummy arguments :
!
CHARACTER (LEN=4), DIMENSION(2), INTENT(IN) :: HLBCX ! X direction LBC type
!
INTEGER, INTENT(IN) :: KGRID ! C grid localisation
!
REAL, DIMENSION(:,:,:), INTENT(INOUT) :: PSRC ! variable at t
REAL, DIMENSION(:,:,:), INTENT(IN) :: PCR ! Courant number
REAL, DIMENSION(:,:,:), INTENT(IN) :: PRHO ! density
REAL, INTENT(IN) :: PTSTEP ! Time step
!
! output source term
REAL, DIMENSION(:,:,:), INTENT(OUT) :: PR
INTEGER :: IZQL,IZQR,IZDQ,IZQ6,IZDMQ,IZQL0,IZQR0,IZQ60,IZFPOS,IZFNEG
!$acc data present( PSRC, PCR, PRHO, PR )
CALL MNH_GET_ZT3D(IZQL,IZQR,IZDQ,IZQ6,IZDMQ,IZQL0,IZQR0,IZQ60,IZFPOS,IZFNEG)
CALL PPM_01_X_D(IIU,IJU,IKU,HLBCX, KGRID, &
& PSRC, PCR, PRHO, PTSTEP, PR, &
& ZT3D(:,:,:,IZQL),ZT3D(:,:,:,IZQR),ZT3D(:,:,:,IZDQ),ZT3D(:,:,:,IZQ6), &
& ZT3D(:,:,:,IZDMQ),ZT3D(:,:,:,IZQL0),ZT3D(:,:,:,IZQR0), ZT3D(:,:,:,IZQ60), &
& ZT3D(:,:,:,IZFPOS),ZT3D(:,:,:,IZFNEG) )
CALL MNH_REL_ZT3D(IZQL,IZQR,IZDQ,IZQ6,IZDMQ,IZQL0,IZQR0,IZQ60,IZFPOS,IZFNEG)
!$acc end data
!
CONTAINS
!
! ########################################################################
SUBROUTINE PPM_01_X_D(IIU,IJU,IKU,HLBCX, KGRID, &
& PSRC, PCR, PRHO, PTSTEP, PR, &
& ZQL,ZQR,ZDQ,ZQ6,ZDMQ,ZQL0,ZQR0,ZQ60,ZFPOS,ZFNEG)
! ########################################################################
#else

ESCOBAR MUNOZ Juan
committed
! ########################################################################
FUNCTION PPM_01_X(HLBCX, KGRID, PSRC, PCR, PRHO, PTSTEP) &
RESULT(PR)
! ########################################################################

ESCOBAR MUNOZ Juan
committed
#endif
!!
!!**** PPM_01_X - PPM_01 fully monotonic PPM advection scheme in X direction
!! Colella notation
!!
!! MODIFICATIONS
!! -------------
!!
!! 11.5.2006. T. Maric - original version
!! J.Escobar 21/03/2013: for HALOK comment all NHALO=1 test
!! J.Escobar 28/06/2018: limit computation on TAB(:,IJS:IJN,:) to avoid unneeded NaN
!! J.Escobr 16/07/2018: still NaN pb => reintroduce initialization of temporary local array
!!
!-------------------------------------------------------------------------------
!
USE MODD_CONF
USE MODE_ll
use mode_mppdb
#ifdef MNH_OPENACC
use mode_msg
#endif

ESCOBAR MUNOZ Juan
committed
#if defined(MNH_BITREP) || defined(MNH_BITREP_OMP)
USE MODI_BITREP
#endif

ESCOBAR MUNOZ Juan
committed
#ifdef MNH_BITREP_OMP
USE MODI_BITREPZ
#endif
USE MODI_GET_HALO
#ifndef MNH_OPENACC
USE MODI_SHUMAN
#else
USE MODI_SHUMAN_DEVICE
#endif
!
IMPLICIT NONE
!
!* 0.1 Declarations of dummy arguments :
!

ESCOBAR MUNOZ Juan
committed
#ifdef MNH_OPENACC
INTEGER , INTENT(IN) :: IIU,IJU,IKU
#endif
CHARACTER (LEN=4), DIMENSION(2), INTENT(IN) :: HLBCX ! X direction LBC type
!
INTEGER, INTENT(IN) :: KGRID ! C grid localisation
!
REAL, DIMENSION(:,:,:), INTENT(INOUT) :: PSRC ! variable at t
REAL, DIMENSION(:,:,:), INTENT(IN) :: PCR ! Courant number
REAL, DIMENSION(:,:,:), INTENT(IN) :: PRHO ! density
REAL, INTENT(IN) :: PTSTEP ! Time step
!
! output source term
#ifndef MNH_OPENACC
REAL, DIMENSION(SIZE(PCR,1),SIZE(PCR,2),SIZE(PCR,3)) :: PR
#else

ESCOBAR MUNOZ Juan
committed
REAL, DIMENSION(IIU,IJU,IKU), INTENT(OUT) :: PR
#endif
!
!* 0.2 Declarations of local variables :
!
INTEGER:: IIB,IJB ! Begining useful area in x,y,z directions
INTEGER:: IIE,IJE ! End useful area in x,y,z directions
!
integer :: ji, jj, jk
#ifndef MNH_OPENACC

ESCOBAR MUNOZ Juan
committed
integer :: iiu, iju, iku
! terms used in parabolic interpolation, dmq, qL, qR, dq, q6
REAL, DIMENSION(SIZE(PCR,1),SIZE(PCR,2),SIZE(PCR,3)) :: ZQL,ZQR
REAL, DIMENSION(SIZE(PCR,1),SIZE(PCR,2),SIZE(PCR,3)) :: ZDQ,ZQ6
REAL, DIMENSION(SIZE(PCR,1),SIZE(PCR,2),SIZE(PCR,3)) :: ZDMQ
!
! extra variables for the initial guess of parabolae parameters
REAL, DIMENSION(SIZE(PCR,1),SIZE(PCR,2),SIZE(PCR,3)) :: ZQL0,ZQR0,ZQ60
!
! advection fluxes
REAL, DIMENSION(SIZE(PCR,1),SIZE(PCR,2),SIZE(PCR,3)) :: ZFPOS, ZFNEG

ESCOBAR MUNOZ Juan
committed
!
!BEG JUAN PPM_LL
INTEGER :: IJS,IJN
!END JUAN PPM_LL
#else
INTEGER :: I,J,K
!

ESCOBAR MUNOZ Juan
committed
!!$!
!!$! terms used in parabolic interpolation, dmq, qL, qR, dq, q6
REAL , DIMENSION(IIU,IJU,IKU) :: &
ZQL,ZQR, ZDQ,ZQ6, ZDMQ &
!!$!
!!$! extra variables for the initial guess of parabolae parameters
, ZQL0,ZQR0,ZQ60 &
!!$!
!!$! advection fluxes
, ZFPOS, ZFNEG
!
INTEGER :: IJS,IJN

ESCOBAR MUNOZ Juan
committed
#endif
LOGICAL :: GWEST , GEAST
!-------------------------------------------------------------------------------

ESCOBAR MUNOZ Juan
committed
!
#ifdef MNH_BITREP_OMP
CALL SBR_FZ(PSRC(:,:,:))
#endif
!

ESCOBAR MUNOZ Juan
committed
!$acc data present( PSRC, PCR, PRHO, PR , &
!$acc & ZQL, ZQR, ZDQ, ZQ6, ZDMQ, ZQL0, ZQR0, ZQ60, ZFPOS, ZFNEG )
IF (MPPDB_INITIALIZED) THEN
!Check all IN arrays
CALL MPPDB_CHECK(PCR, "PPM_01_X beg:PCR")
CALL MPPDB_CHECK(PRHO,"PPM_01_X beg:PRHO")
!Check all INOUT arrays
CALL MPPDB_CHECK(PSRC,"PPM_01_X beg:PSRC")
END IF
!
!* 0.3. COMPUTES THE DOMAIN DIMENSIONS
! ------------------------------
!
CALL GET_INDICE_ll(IIB,IJB,IIE,IJE)
IJS=IJB
IJN=IJE
!
GWEST = LWEST_ll()
GEAST = LEAST_ll()
!
!BEG JUAN PPM_LL
!
!* initialise & update halo & halo2 for PSRC
!
#ifndef MNH_OPENACC

ESCOBAR MUNOZ Juan
committed
iiu = size( PSRC, 1 )
iju = size( PSRC, 2 )
iku = size( PSRC, 3 )
CALL GET_HALO(PSRC, HNAME='PSRC')
!
PR (:,:,:) = PSRC(:,:,:)
ZQL (:,:,:) = PSRC(:,:,:)
ZQR (:,:,:) = PSRC(:,:,:)
ZDQ (:,:,:) = PSRC(:,:,:)
ZQ6 (:,:,:) = PSRC(:,:,:)
ZDMQ (:,:,:) = PSRC(:,:,:)
ZQL0 (:,:,:) = PSRC(:,:,:)
ZQR0 (:,:,:) = PSRC(:,:,:)
ZQ60 (:,:,:) = PSRC(:,:,:)
ZFPOS(:,:,:) = PSRC(:,:,:)
ZFNEG(:,:,:) = PSRC(:,:,:)
#else

ESCOBAR MUNOZ Juan
committed
CALL GET_HALO_D(PSRC,HDIR="01_X", HNAME='PSRC')
!
!$acc kernels

ESCOBAR MUNOZ Juan
committed
!$mnh_do_concurrent (ji=1:iiu,jj=1:iju,jk=1:iku)
PR (ji, jj, jk ) = PSRC(ji, jj, jk )
ZQL (ji, jj, jk ) = PSRC(ji, jj, jk )
ZQR (ji, jj, jk ) = PSRC(ji, jj, jk )
ZDQ (ji, jj, jk ) = PSRC(ji, jj, jk )
ZQ6 (ji, jj, jk ) = PSRC(ji, jj, jk )
ZDMQ (ji, jj, jk ) = PSRC(ji, jj, jk )
ZQL0 (ji, jj, jk ) = PSRC(ji, jj, jk )
ZQR0 (ji, jj, jk ) = PSRC(ji, jj, jk )
ZQ60 (ji, jj, jk ) = PSRC(ji, jj, jk )

ESCOBAR MUNOZ Juan
committed
!$mnh_end_do()
!

ESCOBAR MUNOZ Juan
committed
#if 0
ZFPOS(:,1:IJS,:)=PSRC(:,1:IJS,:)
ZFNEG(:,1:IJS,:)=PSRC(:,1:IJS,:)
ZFPOS(:,IJN:,:)=PSRC(:,IJN:,:)
ZFNEG(:,IJN:,:)=PSRC(:,IJN:,:)
#else
ZFPOS(:,:,:) = PSRC(:,:,:)
ZFNEG(:,:,:) = PSRC(:,:,:)

ESCOBAR MUNOZ Juan
committed
#endif
!$acc end kernels
#endif
!
!-------------------------------------------------------------------------------
!
SELECT CASE ( HLBCX(1) ) ! X direction LBC type: (1) for left side
!
! 1.1 CYCLIC BOUNDARY CONDITIONS IN X DIRECTION
! -----------------------------------------
!
CASE ('CYCL','WALL') ! In that case one must have HLBCX(1) == HLBCX(2)
#ifdef MNH_OPENACC
call Print_msg( NVERB_ERROR, 'GEN', 'PPM_01_X', 'OpenACC: CYCL/WALL boundaries not yet implemented' )
#endif
!
! calculate dmq

ESCOBAR MUNOZ Juan
committed
ZDMQ = DIF2X(PSRC)
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
!
! monotonize the difference followinq eq. 5 in Lin94
!
!BEG JUAN PPM_LL01
!
! ZDMQ(i) = Fct[ ZDMQ(i),PSRC(i),PSRC(i-1),PSRC(i+1) ]
!
ZDMQ(IIB:IIE,IJS:IJN,:) = &
SIGN( (MIN( ABS(ZDMQ(IIB:IIE,IJS:IJN,:)),2.0*(PSRC(IIB:IIE,IJS:IJN,:) - &
MIN(PSRC(IIB-1:IIE-1,IJS:IJN,:),PSRC(IIB:IIE,IJS:IJN,:),PSRC(IIB+1:IIE+1,IJS:IJN,:))), &
2.0*(MAX(PSRC(IIB-1:IIE-1,IJS:IJN,:),PSRC(IIB:IIE,IJS:IJN,:),PSRC(IIB+1:IIE+1,IJS:IJN,:)) - &
PSRC(IIB:IIE,IJS:IJN,:)) )), ZDMQ(IIB:IIE,IJS:IJN,:) )
!
! WEST BOUND
!
!!$ ZDMQ(IIB-1,:,:) = &
!!$ SIGN( (MIN( ABS(ZDMQ(IIB-1,:,:)), 2.0*(PSRC(IIB-1,:,:) - &
!!$ MIN(PSRC(IIE-1,:,:),PSRC(IIB-1,:,:),PSRC(IIB,:,:))), &
!!$ 2.0*(MAX(PSRC(IIE-1,:,:),PSRC(IIB-1,:,:),PSRC(IIB,:,:)) - &
!!$ PSRC(IIB-1,:,:)) )), ZDMQ(IIB-1,:,:) )
!
! EAST BOUND
!
!!$ ZDMQ(IIE+1,:,:) = &
!!$ SIGN( (MIN( ABS(ZDMQ(IIE+1,:,:)), 2.0*(PSRC(IIE+1,:,:) - &
!!$ MIN(PSRC(IIE,:,:),PSRC(IIE+1,:,:),PSRC(IIB+1,:,:))), &
!!$ 2.0*(MAX(PSRC(IIE,:,:),PSRC(IIE+1,:,:),PSRC(IIB+1,:,:)) - &
!!$ PSRC(IIE+1,:,:)) )), ZDMQ(IIE+1,:,:) )
!
! update ZDMQ HALO before next/further utilisation
!
CALL GET_HALO(ZDMQ, HNAME='ZDMQ')
!
! calculate qL and qR with the modified dmq
!
! ZQL0(i) = Fct[ PSRC(i),PSRC(i-1),ZDMQ(i),ZDMQ(i-1) ]
!
ZQL0(IIB:IIE+1,IJS:IJN,:) = 0.5*(PSRC(IIB:IIE+1,IJS:IJN,:) + PSRC(IIB-1:IIE,IJS:IJN,:)) - &
(ZDMQ(IIB:IIE+1,IJS:IJN,:) - ZDMQ(IIB-1:IIE,IJS:IJN,:))/6.0
!
CALL GET_HALO(ZQL0, HNAME='ZQL0')
!
! WEST BOUND
!
!!$ ZQL0(IIB-1,:,:) = ZQL0(IIE,:,:) JUAN PPMLL01
!
ZQR0(IIB-1:IIE,IJS:IJN,:) = ZQL0(IIB:IIE+1,IJS:IJN,:)
!
CALL GET_HALO(ZQR0, HNAME='ZQR0')
!
! EAST BOUND
!
!!$ ZQR0(IIE+1,:,:) = ZQR0(IIB,:,:) JUAN PPMLL01
!
! determine initial coefficients of the parabolae
!
ZDQ(:,IJS:IJN,:) = ZQR0(:,IJS:IJN,:) - ZQL0(:,IJS:IJN,:)
ZQ60(:,IJS:IJN,:) = 6.0*(PSRC(:,IJS:IJN,:) - 0.5*(ZQL0(:,IJS:IJN,:) + ZQR0(:,IJS:IJN,:)))
!
! initialize final parabolae parameters
!
ZQL(:,IJS:IJN,:) = ZQL0(:,IJS:IJN,:)
ZQR(:,IJS:IJN,:) = ZQR0(:,IJS:IJN,:)
ZQ6(:,IJS:IJN,:) = ZQ60(:,IJS:IJN,:)
!
! eliminate over and undershoots and create qL and qR as in Lin96
!
WHERE ( ZDMQ(:,IJS:IJN,:) == 0.0 )
ZQL(:,IJS:IJN,:) = PSRC(:,IJS:IJN,:)
ZQR(:,IJS:IJN,:) = PSRC(:,IJS:IJN,:)
ZQ6(:,IJS:IJN,:) = 0.0

ESCOBAR MUNOZ Juan
committed
#if !defined(MNH_BITREP) && !defined(MNH_BITREP_OMP)
ELSEWHERE ( ZQ60(:,IJS:IJN,:)*ZDQ(:,IJS:IJN,:) < -(ZDQ(:,IJS:IJN,:))**2 )
#else
ELSEWHERE ( ZQ60(:,IJS:IJN,:)*ZDQ(:,IJS:IJN,:) < -BR_P2(ZDQ(:,IJS:IJN,:)) )
#endif
ZQ6(:,IJS:IJN,:) = 3.0*(ZQL0(:,IJS:IJN,:) - PSRC(:,IJS:IJN,:))
ZQR(:,IJS:IJN,:) = ZQL0(:,IJS:IJN,:) - ZQ6(:,IJS:IJN,:)
ZQL(:,IJS:IJN,:) = ZQL0(:,IJS:IJN,:)

ESCOBAR MUNOZ Juan
committed
#if !defined(MNH_BITREP) && !defined(MNH_BITREP_OMP)
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
ELSEWHERE ( ZQ60(:,IJS:IJN,:)*ZDQ(:,IJS:IJN,:) > (ZDQ(:,IJS:IJN,:))**2 )
#else
ELSEWHERE ( ZQ60(:,IJS:IJN,:)*ZDQ(:,IJS:IJN,:) > BR_P2(ZDQ(:,IJS:IJN,:)) )
#endif
ZQ6(:,IJS:IJN,:) = 3.0*(ZQR0(:,IJS:IJN,:) - PSRC(:,IJS:IJN,:))
ZQL(:,IJS:IJN,:) = ZQR0(:,IJS:IJN,:) - ZQ6(:,IJS:IJN,:)
ZQR(:,IJS:IJN,:) = ZQR0(:,IJS:IJN,:)
END WHERE
!
! recalculate coefficients of the parabolae
!
ZDQ(:,IJS:IJN,:) = ZQR(:,IJS:IJN,:) - ZQL(:,IJS:IJN,:)
!
! and finally calculate fluxes for the advection
!
! ZFPOS(i) = Fct[ ZQR(i-1),PCR(i),ZDQ(i-1),ZQ6(i-1) ]
!
ZFPOS(IIB:IIE+1,IJS:IJN,:) = ZQR(IIB-1:IIE,IJS:IJN,:) - 0.5*PCR(IIB:IIE+1,IJS:IJN,:) * &
(ZDQ(IIB-1:IIE,IJS:IJN,:) - (1.0 - 2.0*PCR(IIB:IIE+1,IJS:IJN,:)/3.0) &
* ZQ6(IIB-1:IIE,IJS:IJN,:))
!
CALL GET_HALO(ZFPOS, HNAME='ZFPOS')
!
! WEST BOUND
!
! PPOSX(IIB-1,:,:) is not important for the calc of advection so
! we set it to 0
!!$ ZFPOS(IIB-1,:,:) = 0.0 JUANPPMLL01
!
ZFNEG(:,IJS:IJN,:) = ZQL(:,IJS:IJN,:) - 0.5*PCR(:,IJS:IJN,:) * &
( ZDQ(:,IJS:IJN,:) + (1.0 + 2.0*PCR(:,IJS:IJN,:)/3.0) * ZQ6(:,IJS:IJN,:) )
!
CALL GET_HALO(ZFNEG, HNAME='ZFNEG')
!
! advect the actual field in X direction by U*dt
!
#ifndef MNH_OPENACC
PR = DXF( PCR*MXM(PRHO)*( ZFPOS*(0.5+SIGN(0.5,PCR)) + &
ZFNEG*(0.5-SIGN(0.5,PCR)) ) )
#else
call Print_msg( NVERB_ERROR, 'GEN', 'PPM_01_X', 'OpenACC: CYCL/WALL boundaries not yet implemented' )
#endif
CALL GET_HALO(PR, HNAME='PR')
!
!
!* 1.2 NON-CYCLIC BOUNDARY CONDITIONS IN THE X DIRECTION
! -------------------------------------------------
!
CASE('OPEN')
!
! calculate dmq

ESCOBAR MUNOZ Juan
committed
!
#ifndef MNH_OPENACC
ZDMQ = DIF2X(PSRC)
#else
CALL DIF2X_DEVICE(ZDMQ,PSRC)
#endif
!$acc kernels
!
! overwrite the values on the boundary to get second order difference
! for qL and qR at the boundary
!
! WEST BOUND
!
IF (GWEST) THEN
ZDMQ(IIB-1,IJS:IJN,:) = -ZDMQ(IIB,IJS:IJN,:)
ENDIF
!
! EAST BOUND
!
IF (GEAST) THEN
ZDMQ(IIE+1,IJS:IJN,:) = -ZDMQ(IIE,IJS:IJN,:)
ENDIF
!
! monotonize the difference followinq eq. 5 in Lin94
!
! ZDMQ(i) = Fct[ ZDMQ(i),PSRC(i),PSRC(i-1),PSRC(i+1) ]
!

ESCOBAR MUNOZ Juan
committed
!$acc loop independent collapse(3)
do jk = 1, iku
do jj = ijs, ijn
do ji = iib, iie
ZDMQ(ji, jj, jk ) = SIGN( &
MIN( ABS(ZDMQ(ji, jj, jk )), &
2.0 * ( PSRC(ji, jj, jk ) &
- MIN(PSRC(ji - 1, jj, jk ),PSRC(ji, jj, jk ),PSRC(ji + 1, jj, jk )) ), &
2.0 * (-PSRC(ji, jj, jk ) &
+ MAX(PSRC(ji - 1, jj, jk ),PSRC(ji, jj, jk ),PSRC(ji + 1, jj, jk )) ) ), &
ZDMQ(ji, jj, jk ) )

ESCOBAR MUNOZ Juan
committed
end do
end do
end do
!
! WEST BOUND
!
!!$ ZDMQ(IIB-1,:,:) = &
!!$ SIGN( (MIN( ABS(ZDMQ(IIB-1,:,:)), 2.0*(PSRC(IIB-1,:,:) - &
!!$ MIN(PSRC(IIE-1,:,:),PSRC(IIB-1,:,:),PSRC(IIB,:,:))), &
!!$ 2.0*(MAX(PSRC(IIE-1,:,:),PSRC(IIB-1,:,:),PSRC(IIB,:,:)) - &
!!$ PSRC(IIB-1,:,:)) )), ZDMQ(IIB-1,:,:) )
!
! EAST BOUND
!
!!$ ZDMQ(IIE+1,:,:) = &
!!$ SIGN( (MIN( ABS(ZDMQ(IIE+1,:,:)), 2.0*(PSRC(IIE+1,:,:) - &
!!$ MIN(PSRC(IIE,:,:),PSRC(IIE+1,:,:),PSRC(IIB+1,:,:))), &
!!$ 2.0*(MAX(PSRC(IIE,:,:),PSRC(IIE+1,:,:),PSRC(IIB+1,:,:)) - &
!!$ PSRC(IIE+1,:,:)) )), ZDMQ(IIE+1,:,:) )
!
!
! update ZDMQ HALO before next/further utilisation
!
#ifndef MNH_OPENACC
CALL GET_HALO(ZDMQ, HNAME='ZDMQ')
#else
!$acc end kernels

ESCOBAR MUNOZ Juan
committed
CALL GET_HALO_D(ZDMQ, HDIR="01_X", HNAME='ZDMQ')
#endif
!$acc kernels
!
! calculate qL and qR
!
! ZQL0(i) = Fct[ PSRC(i),PSRC(i-1),ZDMQ(i),ZDMQ(i-1) ]
!

ESCOBAR MUNOZ Juan
committed
!$acc loop independent collapse(3)
do jk = 1, iku
do jj = ijs, ijn
do ji = iib, iie + 1
ZQL0(ji, jj, jk ) = 0.5 * ( PSRC(ji, jj, jk ) + PSRC(ji-1, jj, jk ) ) - ( ZDMQ(ji, jj, jk ) - ZDMQ(ji-1, jj, jk ) ) / 6.0

ESCOBAR MUNOZ Juan
committed
end do
end do
end do
!
#ifndef MNH_OPENACC
CALL GET_HALO(ZQL0, HNAME='ZQL0')
#else
!$acc end kernels

ESCOBAR MUNOZ Juan
committed
CALL GET_HALO_D(ZQL0,HDIR="01_X", HNAME='ZQL0')
!$acc kernels
#endif
!
! WEST BOUND
!
IF (GWEST) THEN
ZQL0(IIB-1,IJS:IJN,:) = ZQL0(IIB,IJS:IJN,:)
ENDIF
!
ZQR0(IIB-1:IIE,IJS:IJN,:) = ZQL0(IIB:IIE+1,IJS:IJN,:)
!
#ifndef MNH_OPENACC
CALL GET_HALO(ZQR0, HNAME='ZQR0')
#else

ESCOBAR MUNOZ Juan
committed
!$acc end kernels
CALL GET_HALO_D(ZQR0, HDIR="01_X", HNAME='ZQR0')
!$acc kernels
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
#endif
!
! EAST BOUND
!
IF (GEAST) THEN
ZQR0(IIE+1,IJS:IJN,:) = ZQR0(IIE,IJS:IJN,:)
ENDIF
#ifndef MNH_OPENACC
!
! determine initial coefficients of the parabolae
!
ZDQ(:,IJS:IJN,:) = ZQR0(:,IJS:IJN,:) - ZQL0(:,IJS:IJN,:)
ZQ60(:,IJS:IJN,:) = 6.0*(PSRC(:,IJS:IJN,:) - 0.5*(ZQL0(:,IJS:IJN,:) + ZQR0(:,IJS:IJN,:)))
!
! initialize final parabolae parameters
!
ZQL(:,IJS:IJN,:) = ZQL0(:,IJS:IJN,:)
ZQR(:,IJS:IJN,:) = ZQR0(:,IJS:IJN,:)
ZQ6(:,IJS:IJN,:) = ZQ60(:,IJS:IJN,:)
!
! eliminate over and undershoots and create qL and qR as in Lin96
!
WHERE ( ZDMQ(:,IJS:IJN,:) == 0.0 )
ZQL(:,IJS:IJN,:) = PSRC(:,IJS:IJN,:)
ZQR(:,IJS:IJN,:) = PSRC(:,IJS:IJN,:)
ZQ6(:,IJS:IJN,:) = 0.0
ELSEWHERE ( ZQ60(:,IJS:IJN,:)*ZDQ(:,IJS:IJN,:) < -ZDQ(:,IJS:IJN,:)*ZDQ(:,IJS:IJN,:) )
ZQ6(:,IJS:IJN,:) = 3.0*(ZQL0(:,IJS:IJN,:) - PSRC(:,IJS:IJN,:))
ZQR(:,IJS:IJN,:) = ZQL0(:,IJS:IJN,:) - ZQ6(:,IJS:IJN,:)
ZQL(:,IJS:IJN,:) = ZQL0(:,IJS:IJN,:)
ELSEWHERE ( ZQ60(:,IJS:IJN,:)*ZDQ(:,IJS:IJN,:) > ZDQ(:,IJS:IJN,:)*ZDQ(:,IJS:IJN,:) )
ZQ6(:,IJS:IJN,:) = 3.0*(ZQR0(:,IJS:IJN,:) - PSRC(:,IJS:IJN,:))
ZQL(:,IJS:IJN,:) = ZQR0(:,IJS:IJN,:) - ZQ6(:,IJS:IJN,:)
ZQR(:,IJS:IJN,:) = ZQR0(:,IJS:IJN,:)
END WHERE
!
! recalculate coefficients of the parabolae
!
ZDQ(:,IJS:IJN,:) = ZQR(:,IJS:IJN,:) - ZQL(:,IJS:IJN,:)
#else

ESCOBAR MUNOZ Juan
committed
!$acc loop independent collapse(3)
DO K=1,IKU
DO J = IJS,IJN
! acc loop vector(24)
DO I=1,IIU
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
!
! determine initial coefficients of the parabolae
!
ZDQ (I,J,K)= ZQR0(I,J,K) - ZQL0(I,J,K)
ZQ60(I,J,K) = 6.0*(PSRC(I,J,K) - 0.5*(ZQL0(I,J,K) + ZQR0(I,J,K)))
!
! initialize final parabolae parameters
!
ZQL(I,J,K) = ZQL0(I,J,K)
ZQR(I,J,K) = ZQR0(I,J,K)
ZQ6(I,J,K) = ZQ60(I,J,K)
!
! eliminate over and undershoots and create qL and qR as in Lin96
!
IF ( ZDMQ(I,J,K) == 0.0 ) THEN
ZQL(I,J,K) = PSRC(I,J,K)
ZQR(I,J,K) = PSRC(I,J,K)
ZQ6(I,J,K) = 0.0
ELSEIF ( ZQ60(I,J,K)*ZDQ(I,J,K) < -ZDQ(I,J,K)*ZDQ(I,J,K) ) THEN
ZQ6(I,J,K) = 3.0*(ZQL0(I,J,K) - PSRC(I,J,K))
ZQR(I,J,K) = ZQL0(I,J,K) - ZQ6(I,J,K)
ZQL(I,J,K) = ZQL0(I,J,K)
ELSEIF ( ZQ60(I,J,K)*ZDQ(I,J,K) > ZDQ(I,J,K)*ZDQ(I,J,K) ) THEN
ZQ6(I,J,K) = 3.0*(ZQR0(I,J,K) - PSRC(I,J,K))
ZQL(I,J,K) = ZQR0(I,J,K) - ZQ6(I,J,K)
ZQR(I,J,K) = ZQR0(I,J,K)
ENDIF
!
! recalculate coefficients of the parabolae
!
ZDQ(I,J,K) = ZQR(I,J,K) - ZQL(I,J,K)

ESCOBAR MUNOZ Juan
committed
ENDDO ; ENDDO ; ENDDO
#endif
!
! and finally calculate fluxes for the advection
!
!
! ZFPOS(i) = Fct[ ZQR(i-1),PCR(i),ZDQ(i-1),ZQ6(i-1) ]
!
!!$ ZFPOS(IIB+1:IIE+1,:,:) = ZQR(IIB:IIE,:,:) - 0.5*PCR(IIB+1:IIE+1,:,:) * &
!!$ (ZDQ(IIB:IIE,:,:) - (1.0 - 2.0*PCR(IIB+1:IIE+1,:,:)/3.0) &
!!$ * ZQ6(IIB:IIE,:,:))

ESCOBAR MUNOZ Juan
committed
!$acc loop independent collapse(3)
do jk = 1, iku
do jj = ijs, ijn
do ji = iib, iie + 1
ZFPOS(ji, jj, jk ) = ZQR(ji - 1, jj, jk ) - 0.5 * PCR(ji, jj, jk ) &
* ( ZDQ(ji - 1, jj, jk) - (1.0 - 2.0 * PCR(ji, jj, jk ) / 3.0 ) &
* ZQ6(ji - 1, jj, jk) )

ESCOBAR MUNOZ Juan
committed
end do
end do
end do
!
!
#ifndef MNH_OPENACC
CALL GET_HALO(ZFPOS, HNAME='ZFPOS')
#else
!$acc end kernels

ESCOBAR MUNOZ Juan
committed
CALL GET_HALO_D(ZFPOS, HDIR="01_X", HNAME='ZFPOS')
!$acc kernels
#endif
!
!
! WEST BOUND
!
! advection flux at open boundary when u(IIB) > 0
!
IF (GWEST) THEN
ZFPOS(IIB,IJS:IJN,:) = (PSRC(IIB-1,IJS:IJN,:) - ZQR(IIB-1,IJS:IJN,:))*PCR(IIB,IJS:IJN,:) + &
ZQR(IIB-1,IJS:IJN,:)
! PPOSX(IIB-1,:,:) is not important for the calc of advection so
! we set it to 0
!!$ ZFPOS(IIB-1,:,:) = 0.0
ENDIF
!
!!$ ZFNEG(IIB-1:IIE,:,:) = ZQL(IIB-1:IIE,:,:) - 0.5*PCR(IIB-1:IIE,:,:) * &
!!$ (ZDQ(IIB-1:IIE,:,:) + (1.0 + 2.0*PCR(IIB-1:IIE,:,:)/3.0) &
!!$ * ZQ6(IIB-1:IIE,:,:))

ESCOBAR MUNOZ Juan
committed
!$acc loop independent collapse(3)
do jk = 1, iku
do jj = ijs, ijn
do ji = 1, iiu
ZFNEG(ji, jj, jk ) = ZQL(ji, jj, jk ) - 0.5*PCR(ji, jj, jk ) * &
( ZDQ(ji, jj, jk ) + (1.0 + 2.0*PCR(ji, jj, jk )/3.0) * ZQ6(ji, jj, jk ) )

ESCOBAR MUNOZ Juan
committed
end do
end do
end do
!
#ifndef MNH_OPENACC
CALL GET_HALO(ZFNEG, HNAME='ZFNEG')
#else
!$acc end kernels

ESCOBAR MUNOZ Juan
committed
CALL GET_HALO_D(ZFNEG, HDIR="01_X", HNAME='ZFNEG')
!$acc kernels
#endif
!
! EAST BOUND
!
! advection flux at open boundary when u(IIE+1) < 0
IF (GEAST) THEN
ZFNEG(IIE+1,IJS:IJN,:) = (ZQR(IIE,IJS:IJN,:)-PSRC(IIE+1,IJS:IJN,:))*PCR(IIE+1,IJS:IJN,:) + &
ZQR(IIE,IJS:IJN,:)
ENDIF
!
! advect the actual field in X direction by U*dt
!
#ifndef MNH_OPENACC
PR = DXF( PCR*MXM(PRHO)*( ZFPOS*(0.5+SIGN(0.5,PCR)) + &
ZFNEG*(0.5-SIGN(0.5,PCR)) ) )
CALL GET_HALO(PR, HNAME='PR')
#else
!mxm(ZQL,PRHO)

ESCOBAR MUNOZ Juan
committed
!$acc end kernels
CALL MXM_DEVICE(PRHO,ZQL)

ESCOBAR MUNOZ Juan
committed
!$acc kernels
where ( PCR(:,:,:) > 0. )
ZQR(:,:,:) = PCR(:,:,:) * ZQL(:,:,:) * ZFPOS(:,:,:)
elsewhere
ZQR(:,:,:) = PCR(:,:,:) * ZQL(:,:,:) * ZFNEG(:,:,:)
end where
!dxf(PR,ZQR)
!$acc end kernels
CALL DXF_DEVICE(ZQR,PR)

ESCOBAR MUNOZ Juan
committed
CALL GET_HALO_D(PR, HDIR="01_X", HNAME='PR')
#endif
!
END SELECT
!

ESCOBAR MUNOZ Juan
committed
#ifdef MNH_BITREP_OMP
CALL SBR_FZ(PR(:,:,:))
#endif
!
IF (MPPDB_INITIALIZED) THEN
!Check all INOUT arrays
CALL MPPDB_CHECK(PSRC,"PPM_01_X end:PSRC")
!Check all OUT arrays
CALL MPPDB_CHECK(PR,"PPM_01_X end:PR")
END IF
!$acc end data

ESCOBAR MUNOZ Juan
committed
#ifndef MNH_OPENACC
CONTAINS

ESCOBAR MUNOZ Juan
committed
#else
END SUBROUTINE PPM_01_X_D
#endif
!
!-------------------------------------------------------------------------------
!-------------------------------------------------------------------------------
!
! ########################################################################

ESCOBAR MUNOZ Juan
committed
FUNCTION DIF2X(PQ) RESULT(DQ)
! ########################################################################