Newer
Older
!MNH_LIC Copyright 1994-2014 CNRS, Meteo-France and Universite Paul Sabatier
!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.
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
!-----------------------------------------------------------------
!--------------- special set of characters for RCS information
!-----------------------------------------------------------------
! $Source$ $Revision$ $Date$
!-----------------------------------------------------------------
! ################
MODULE MODI_TRIDZ
! ################
!
INTERFACE
!
SUBROUTINE TRIDZ(HLUOUT,HLBCX,HLBCY, &
PMAP,PDXHAT,PDYHAT,PDXHATM,PDYHATM,PRHOM, &
PAF,PCF,PTRIGSX,PTRIGSY,KIFAXX,KIFAXY, &
PRHODJ,PTHVREF,PZZ,PBFY,PBFB,&
PBF_SXP2_YP1_Z)!JUAN Z_SPLITING
!
IMPLICIT NONE
!
CHARACTER (LEN=*), INTENT(IN) :: HLUOUT ! output listing name
CHARACTER (LEN=4), DIMENSION(2), INTENT(IN) :: HLBCX ! x-direction LBC type
CHARACTER (LEN=4), DIMENSION(2), INTENT(IN) :: HLBCY ! y-direction LBC type
!
REAL, DIMENSION(:,:,:), INTENT(IN) :: PRHODJ ! density of reference * J
REAL, DIMENSION(:,:,:), INTENT(IN) :: PTHVREF ! Virtual Potential
! Temperature of the reference state
!
REAL, DIMENSION(:,:), INTENT(IN) :: PMAP ! scale factor
!
REAL, DIMENSION(:,:,:), INTENT(IN) :: PZZ ! height z
!
REAL, DIMENSION(:), INTENT(IN) :: PDXHAT ! Stretching in x direction
REAL, DIMENSION(:), INTENT(IN) :: PDYHAT ! Stretching in y direction
!
REAL, INTENT(OUT) :: PDXHATM ! mean grid increment in the x
! direction
REAL, INTENT(OUT) :: PDYHATM ! mean grid increment in the y
! direction
!
REAL, DIMENSION (:), INTENT(OUT) :: PRHOM ! mean of XRHODJ on the plane
! x y localized at a mass
! level
!
REAL, DIMENSION(:), INTENT(OUT) :: PAF,PCF ! vectors giving the nonvanishing
REAL, DIMENSION(:,:,:), INTENT(OUT) :: PBFY ! elements (yslice) of the tri-diag.
! matrix in the pressure eq.
!JUAN
REAL, DIMENSION(:,:,:), INTENT(OUT) :: PBFB ! elements (bsplit slide) of the tri-diag.
! matrix in the pressure eq.
REAL, DIMENSION(:,:,:), INTENT(OUT) :: PBF_SXP2_YP1_Z ! elements of the tri-diag. SXP2_YP1_Z-slide
! matrix in the pressure eq
!JUAN
!
! arrays of sin or cos values
! for the FFT :
REAL, DIMENSION(:), INTENT(OUT) :: PTRIGSX ! - along x
REAL, DIMENSION(:), INTENT(OUT) :: PTRIGSY ! - along y
!
! decomposition in prime
! numbers for the FFT:
INTEGER, DIMENSION(19), INTENT(OUT) :: KIFAXX ! - along x
INTEGER, DIMENSION(19), INTENT(OUT) :: KIFAXY ! - along y
!
END SUBROUTINE TRIDZ
!
END INTERFACE
!
END MODULE MODI_TRIDZ
!
! ###################################################################
SUBROUTINE TRIDZ(HLUOUT,HLBCX,HLBCY, &
PMAP,PDXHAT,PDYHAT,PDXHATM,PDYHATM,PRHOM, &
PAF,PCF,PTRIGSX,PTRIGSY,KIFAXX,KIFAXY, &
PRHODJ,PTHVREF,PZZ,PBFY,PBFB,&
PBF_SXP2_YP1_Z) !JUAN Z_SPLITING
! ####################################################################
!
!!**** *TRIDZ * - Compute coefficients for the flat operator
!!
!! PURPOSE
!! -------
! The purpose of this routine is to compute the vertical time independent
! coefficients a(k), b(k), c(k) required for the calculation of the "flat"
! (i.e. neglecting the orography) operator Laplacian. RHOJ is averaged on
! the whole horizontal domain. The form of the eigenvalues of the flat
! operator depends on the lateral boundary conditions. Furthermore, this
! routine initializes TRIGS and IFAX arrays required for the FFT transform
! used in the routine PRECOND.
!
!!** METHOD
!! ------
!! The forms of the eigenvalues of the horizontal Laplacian are given by:
!! Cyclic conditions:
!! -----------------
!! <rhoj> 2 ( pi ) <rhoj> 2 ( pi )
!! b(m,n) = -4 ----------- sin (----- m ) -4 ----------- sin (----- n )
!! <dxx> <dxx> ( imax ) <dyy> <dyy> ( jmax )
!!
!! Open conditions:
!! -----------------
!! <rhoj> 2 ( pi ) <rhoj> 2 ( pi )
!! b(m,n) = -4 ----------- sin (----- m ) -4 ----------- sin (----- n )
!! <dxx> <dxx> ( 2imax ) <dyy> <dyy> ( 2jmax )
!!
!! Cyclic condition along x and open condition along y:
!! ------------------------------------------------------
!! <rhoj> 2 ( pi ) <rhoj> 2 ( pi )
!! b(m,n) = -4 ----------- sin (----- m ) -4 ----------- sin (----- n )
!! <dxx> <dxx> ( imax ) <dyy> <dyy> ( 2jmax )
!!
!! Open condition along x and cyclic condition along y:
!! ------------------------------------------------------
!! <rhoj> 2 ( pi ) <rhoj> 2 ( pi )
!! b(m,n) = -4 ----------- sin (----- m ) -4 ----------- sin (----- n )
!! <dxx> <dxx> ( 2imax ) <dyy> <dyy> ( jmax )
!!
!! where m = 0,1,2....imax-1, n = 0,1,2....jmax-1
!! Note that rhoj contains the Jacobian J = Deltax*Deltay*Deltaz = volume of
!! an elementary mesh.
!!
!! EXTERNAL
!! --------
!! Function FFTFAX: initialization of TRIGSX,IFAXX,TRIGSY,IFAXY for
!! the FFT transform
!! GET_DIM_EXT_ll : get extended sub-domain sizes
!! GET_INDICE_ll : get physical sub-domain bounds
!! GET_DIM_PHYS_ll : get physical sub-domain sizes
!! GET_GLOBALDIMS_ll : get physical global domain sizes
!! GET_OR_ll : get origine coordonates of the physical sub-domain in global indices
!! REDUCESUM_ll : sum into a scalar variable
!! GET_SLICE_ll : get a slice of the global domain
!!
!! IMPLICIT ARGUMENTS
!! ------------------
!! Module MODD_CST : define constants
!! XPI : pi
!! XCPD
!! Module MODD_PARAMETERS: declaration of parameter variables
!! JPHEXT, JPVEXT: define the number of marginal points out of the
!! physical domain along horizontal and vertical directions respectively
!! Module MODD_CONF: model configurations
!! LCARTESIAN: logical for CARTESIAN geometry
!! .TRUE. = Cartesian geometry used
!! L2D: logical for 2D model version
!!
!! REFERENCE
!! ---------
!! Book2 of documentation (routine TRIDZ)
!!
!! AUTHOR
!! ------
!! P. HÅreil and J. Stein * Meteo France *
!!
!! MODIFICATIONS
!! -------------
!! Original 25/07/94
!! 14/04/95 (J. Stein) bug in the ZDZM computation
!! ( stretched case)
!! 8/07/96 (P. Jabouille) change the FFT initialization
!! which now works for odd number.
!! 14/01/97 Durran anelastic equation (Stein,Lafore)
!! 15/06/98 (D.Lugato, R.Guivarch) Parallelisation
!! 10/08/98 (N. Asencio) add parallel code
!! use PDXHAT, PDYHAT and not PXHAT,PYHAT
!! PBFY is initialized
!! 20/08/00 (J. Stein, J. Escobar) optimisation of the solver
!! PBFY transposition
!! 14/03/02 (P. Jabouille) set values for meaningless spectral coefficients
!! (to avoid problem in bouissinesq configuration)
!! J.Escobar : 15/09/2015 : WENO5 & JPHEXT <> 1
!------------------------------------------------------------------------------
!
!* 0. DECLARATIONS
! ------------
USE MODD_CST
USE MODD_CONF
USE MODD_PARAMETERS
!
USE MODE_ll
USE MODE_IO_ll
USE MODE_FM
!JUAN P1/P2 SPLITTING
USE MODE_SPLITTINGZ_ll , ONLY : GET_DIM_EXTZ_ll,GET_ORZ_ll,LWESTZ_ll,LSOUTHZ_ll
!JUAN
!
!JUAN
USE MODE_REPRO_SUM
!JUAN
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
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
!
IMPLICIT NONE
!
!
!* 0.1 declarations of arguments
!
!
!
CHARACTER (LEN=*), INTENT(IN) :: HLUOUT ! output listing name
CHARACTER (LEN=4), DIMENSION(2), INTENT(IN) :: HLBCX ! x-direction LBC type
CHARACTER (LEN=4), DIMENSION(2), INTENT(IN) :: HLBCY ! y-direction LBC type
!
REAL, DIMENSION(:,:,:), INTENT(IN) :: PRHODJ ! density of reference * J
REAL, DIMENSION(:,:,:), INTENT(IN) :: PTHVREF ! Virtual Potential
! Temperature of the reference state
!
REAL, DIMENSION(:,:), INTENT(IN) :: PMAP ! scale factor
!
REAL, DIMENSION(:,:,:), INTENT(IN) :: PZZ ! height z
!
REAL, DIMENSION(:), INTENT(IN) :: PDXHAT ! Stretching in x direction
REAL, DIMENSION(:), INTENT(IN) :: PDYHAT ! Stretching in y direction
!
REAL, INTENT(OUT) :: PDXHATM ! mean grid increment in the x
! direction
REAL, INTENT(OUT) :: PDYHATM ! mean grid increment in the y
! direction
!
REAL, DIMENSION (:), INTENT(OUT) :: PRHOM ! mean of XRHODJ on the plane
! x y localized at a mass
! level
!
REAL, DIMENSION(:), INTENT(OUT) :: PAF,PCF ! vectors giving the nonvanishing
REAL, DIMENSION(:,:,:), INTENT(OUT) :: PBFY ! elements (yslice) of the tri-diag.
! matrix in the pressure eq. which is transposed. PBFY is a y-slices structure
!JUAN
REAL, DIMENSION(:,:,:), INTENT(OUT) :: PBFB ! elements (bsplit slide) of the tri-diag.
! matrix in the pressure eq.
REAL, DIMENSION(:,:,:), INTENT(OUT) :: PBF_SXP2_YP1_Z ! elements of the tri-diag. SXP2_YP1_Z-slide
! matrix in the pressure eq.
!JUAN
!
! arrays of sin or cos values
! for the FFT :
REAL, DIMENSION(:), INTENT(OUT) :: PTRIGSX ! - along x
REAL, DIMENSION(:), INTENT(OUT) :: PTRIGSY ! - along y
!
! decomposition in prime
! numbers for the FFT:
INTEGER, DIMENSION(19), INTENT(OUT) :: KIFAXX ! - along x
INTEGER, DIMENSION(19), INTENT(OUT) :: KIFAXY ! - along y
!
!* 0.2 declarations of local variables
!
INTEGER :: IRESP ! FM return code
INTEGER :: ILUOUT ! Logical unit number for
! output-listing
INTEGER :: IIB,IIE,IJB,IJE,IKB,IKE ! indice values of the physical subdomain
INTEGER :: IKU ! size of the arrays along z
INTEGER :: IIB_ll,IIE_ll,IJB_ll,IJE_ll ! indice values of the physical global domain
INTEGER :: IIMAX,IJMAX ! Number of points of the physical subdomain
INTEGER :: IIMAX_ll,IJMAX_ll ! Number of points of Global physical domain
!
INTEGER :: JI,JJ,JK ! loop indexes
!
INTEGER :: INN ! temporary result for the computation of array TRIGS
!
REAL, DIMENSION (:,:), ALLOCATABLE :: ZEIGEN_ll ! eigenvalues b(m,n) in global representation
REAL, DIMENSION (:), ALLOCATABLE :: ZEIGENX_ll ! used for the computation of ZEIGEN_ll
!
REAL, DIMENSION( SIZE(PDXHAT)) :: ZWORKX ! work array to compute PDXHATM
REAL, DIMENSION( SIZE(PDYHAT)) :: ZWORKY ! work array to compute PDYHATM
!
REAL :: ZGWNX,ZGWNY ! greater wave numbers allowed by the model
! configuration in x and y directions respectively
!
REAL, DIMENSION (SIZE(PZZ,3)) :: ZDZM ! mean of deltaz on the plane x y
! localized at a w-level
!
REAL :: ZANGLE,ZDEL ! needed for the initialization of the arrays used by the FFT
!
REAL :: ZINVMEAN ! inverse of inner points number in an horizontal grid
!
INTEGER :: IINFO_ll ! return code of parallel routine
REAL, DIMENSION (SIZE(PMAP,1)) :: ZXMAP ! extraction of PMAP array along x
REAL, DIMENSION (SIZE(PMAP,2)) :: ZYMAP ! extraction of PMAP array along y
INTEGER :: IORXY_ll,IORYY_ll ! origin's coordinates of the y-slices subdomain
INTEGER :: IIUY_ll,IJUY_ll ! dimensions of the y-slices subdomain
INTEGER :: IXMODE_ll,IYMODE_ll ! number of modes in the x and y direction for global point of view
INTEGER :: IXMODEY_ll,IYMODEY_ll ! number of modes in the x and y direction for y_slice point of view
!JUAN Z_SPLITTING
INTEGER :: IORXB_ll,IORYB_ll ! origin's coordinates of the b-slices subdomain
INTEGER :: IIUB_ll,IJUB_ll ! dimensions of the b-slices subdomain
INTEGER :: IXMODEB_ll,IYMODEB_ll ! number of modes in the x and y direction for b_slice point of view
!
INTEGER :: IORX_SXP2_YP1_Z_ll,IORY_SXP2_YP1_Z_ll ! origin's coordinates of the b-slices subdomain
INTEGER :: IIU_SXP2_YP1_Z_ll,IJU_SXP2_YP1_Z_ll,IKU_SXP2_YP1_Z_ll ! dimensions of the b-slices subdomain
INTEGER :: IXMODE_SXP2_YP1_Z_ll,IYMODE_SXP2_YP1_Z_ll ! number of modes in the x and y direction for b_slice point of view
!JUAN Z_SPLITTING
!JUAN16
!TYPE(DOUBLE_DOUBLE) , DIMENSION (SIZE(PZZ,3)) :: ZRHOM_ll , ZDZM_ll
REAL, ALLOCATABLE, DIMENSION(:,:) :: ZRHOM_2D , ZDZM_2D
!JUAN16
!
!
!
!
!
!------------------------------------------------------------------------------
!
!* 1. INITIALIZATION
! --------------
!
!* 1.1 retrieve a logical unit number
! ------------------------------
!
CALL FMLOOK_ll(HLUOUT,HLUOUT,ILUOUT,IRESP)
!
!* 1.2 compute loop bounds
! -------------------
!
! extended sub-domain
CALL GET_DIM_EXT_ll ('Y',IIUY_ll,IJUY_ll)
!JUAN Z_SPLITTING
CALL GET_DIM_EXT_ll ('B',IIUB_ll,IJUB_ll)
! P1/P2 splitting
CALL GET_DIM_EXTZ_ll('SXP2_YP1_Z',IIU_SXP2_YP1_Z_ll,IJU_SXP2_YP1_Z_ll,IKU_SXP2_YP1_Z_ll)
!JUAN Z_SPLITTING
IKU=SIZE(PRHODJ,3)
!
CALL GET_INDICE_ll (IIB,IJB,IIE,IJE)
IKB=1 +JPVEXT
IKE=IKU -JPVEXT
! physical sub-domain
CALL GET_DIM_PHYS_ll ( 'B',IIMAX,IJMAX)
!
! global physical domain limits
CALL GET_GLOBALDIMS_ll ( IIMAX_ll, IJMAX_ll)
IIB_ll = 1 + JPHEXT
IIE_ll = IIMAX_ll + JPHEXT
IJB_ll = 1 + JPHEXT
IJE_ll = IJMAX_ll + JPHEXT
!
! the use of local array ZEIGENX and ZEIGEN would require some technical modifications
!
ALLOCATE (ZEIGENX_ll(IIMAX_ll+2*JPHEXT))
ALLOCATE (ZEIGEN_ll(IIMAX_ll+2*JPHEXT,IJMAX_ll+2*JPHEXT))
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
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
ZEIGEN_ll = 0.0
! Get the origin coordinates of the extended sub-domain in global landmarks
CALL GET_OR_ll('Y',IORXY_ll,IORYY_ll)
!JUAN Z_SPLITING
CALL GET_OR_ll('B',IORXB_ll,IORYB_ll)
! P1/P2 Splitting
CALL GET_ORZ_ll('SXP2_YP1_Z',IORX_SXP2_YP1_Z_ll,IORY_SXP2_YP1_Z_ll)
!JUAN Z_SPLITING
!
!* 1.3 allocate x-slice array
!
!* 1.4 variables for the eigenvalues computation
!
ZGWNX = XPI/REAL(IIMAX_ll)
ZGWNY = XPI/REAL(IJMAX_ll)
!
!------------------------------------------------------------------------------
!
!* 2. COMPUTE THE AVERAGE OF RHOJ*CPD*THETAVREF ALONG XY
! --------------------------------------------------
!
ZINVMEAN = 1./REAL(IIMAX_ll*IJMAX_ll)
!JUAN16
ALLOCATE(ZRHOM_2D(IIB:IIE, IJB:IJE))
!
DO JK = 1,SIZE(PZZ,3)
IF ( CEQNSYS == 'DUR' .OR. CEQNSYS == 'MAE' ) THEN
DO JJ = IJB,IJE
DO JI = IIB,IIE
ZRHOM_2D(JI,JJ) = PRHODJ(JI,JJ,JK)*XCPD*PTHVREF(JI,JJ,JK)*ZINVMEAN
END DO
END DO
ELSEIF ( CEQNSYS == 'LHE' ) THEN
DO JJ = IJB,IJE
DO JI = IIB,IIE
ZRHOM_2D(JI,JJ) = PRHODJ(JI,JJ,JK)*ZINVMEAN
END DO
END DO
END IF
! global sum
PRHOM(JK) = SUM_DD_R2_ll(ZRHOM_2D)
END DO
!
! global sum
!CALL REDUCESUM_ll(ZRHOM_ll,IINFO_ll)
!PRHOM = ZRHOM_ll
!JUAN16
!
!------------------------------------------------------------------------------
!
!* 3. COMPUTE THE MEAN INCREMENT BETWEEN Z LEVELS
! -------------------------------------------
!
!JUAN16
!ZDZM_ll = 0.
ALLOCATE(ZDZM_2D(IIB:IIE, IJB:IJE))
!
DO JK = IKB-1,IKE
DO JJ = IJB,IJE
DO JI = IIB,IIE
ZDZM_2D(JI,JJ) = (PZZ(JI,JJ,JK+1)-PZZ(JI,JJ,JK))*ZINVMEAN
END DO
END DO
ZDZM(JK) = SUM_DD_R2_ll(ZDZM_2D)
END DO
ZDZM(IKE+1) = ZDZM(IKE)
!
! global sum
!CALL REDUCESUM_ll(ZDZM_ll,IINFO_ll)
!ZDZM = ZDZM_ll
!JUAN16
!
!
! vertical average to arrive at a w-level
DO JK = IKE+1,IKB,-1
ZDZM(JK) = (ZDZM(JK) + ZDZM(JK-1))*0.5
END DO
!
ZDZM(IKB-1) = -999.
!
!------------------------------------------------------------------------------
!
!* 4. COMPUTE THE MEAN INCREMENT BETWEEN X LEVELS
! -------------------------------------------
!
PDXHATM =0.
! . local sum
IF (LCARTESIAN) THEN
PDXHATM = SUM_1DFIELD_ll ( PDXHAT,'X',IIB_ll,IIE_ll,IINFO_ll)
ELSE
! Extraction of x-slice PMAP at j=(IJB_ll+IJE_ll)/2
CALL GET_SLICE_ll (PMAP,'X',(IJB_ll+IJE_ll)/2,ZXMAP(IIB:IIE) &
,IIB,IIE,IINFO_ll)
! initialize the work array = PDXHAT/ZXMAP
ZWORKX(IIB:IIE) = PDXHAT(IIB:IIE)/ ZXMAP (IIB:IIE)
PDXHATM = SUM_1DFIELD_ll ( ZWORKX,'X',IIB_ll,IIE_ll,IINFO_ll)
END IF
! . division to complete sum
PDXHATM = PDXHATM / REAL(IIMAX_ll)
!
!------------------------------------------------------------------------------
!
!* 5. COMPUTE THE MEAN INCREMENT BETWEEN Y LEVELS
! -------------------------------------------
!
PDYHATM = 0.
IF (LCARTESIAN) THEN
PDYHATM = SUM_1DFIELD_ll ( PDYHAT,'Y',IJB_ll,IJE_ll,IINFO_ll)
ELSE
! Extraction of y-slice PMAP at i=IIB_ll+IIE_ll/2
CALL GET_SLICE_ll (PMAP,'Y',(IIB_ll+IIE_ll)/2,ZYMAP(IJB:IJE) &
,IJB,IJE,IINFO_ll)
! initialize the work array = PDYHAT / ZYMAP
ZWORKY(IJB:IJE) = PDYHAT(IJB:IJE) / ZYMAP (IJB:IJE)
PDYHATM = SUM_1DFIELD_ll ( ZWORKY,'Y',IJB_ll,IJE_ll,IINFO_ll)
END IF
! . division to complete sum
PDYHATM= PDYHATM / REAL(IJMAX_ll)
!
!------------------------------------------------------------------------------
!
!* 6. COMPUTE THE OUT-DIAGONAL ELEMENTS A AND C OF THE MATRIX
! -------------------------------------------------------
!
DO JK = IKB,IKE
PAF(JK) = 0.5 * ( PRHOM(JK-1) + PRHOM(JK) ) / ZDZM(JK) **2
PCF(JK) = 0.5 * ( PRHOM(JK) + PRHOM(JK+1) ) / ZDZM(JK+1) **2
END DO
!
! at the upper and lower levels PAF and PCF are computed using the Neumann
! conditions applying on the vertical component of the gradient
!
PAF(IKE+1) = -0.5 * ( PRHOM(IKE) + PRHOM(IKE+1) ) / ZDZM(IKE+1) **2
PCF(IKB-1) = 0.5 * ( PRHOM(IKB-1) + PRHOM(IKB) ) / ZDZM(IKB) **2
!
PAF(IKB-1) = 999.
PCF(IKE+1) = 999.
!------------------------------------------------------------------------------
!* 7. COMPUTE THE DIAGONAL ELEMENTS B OF THE MATRIX
! ---------------------------------------------
!
!* 7.1 compute the horizontal eigenvalues
!
!
!* 7.1.1 compute the eigenvalues along the x direction
!
SELECT CASE (HLBCX(1))
! in the cyclic case, the eigenvalues are the same for two following JM values:
! it corresponds to the real and complex parts of the FFT
CASE('CYCL') ! cyclic case
IXMODE_ll = IIMAX_ll+2*JPHEXT ! +2
IXMODEY_ll = IIUY_ll
IXMODEB_ll = IIUB_ll !JUAN Z_SPLITTING
!
DO JI = 1,IXMODE_ll
ZEIGENX_ll(JI) = - ( 2. * SIN ( (JI-1)/2*ZGWNX ) / PDXHATM )**2
END DO
CASE DEFAULT ! other cases
IXMODE_ll = IIMAX_ll
!
!
IF (LEAST_ll(HSPLITTING='Y')) THEN
IXMODEY_ll = IIUY_ll - 2*JPHEXT ! -2
ELSE
IXMODEY_ll = IIUY_ll
END IF
!JUAN Z_SPLITTING
IF (LEAST_ll(HSPLITTING='B')) THEN
IXMODEB_ll = IIUB_ll - 2*JPHEXT ! -2
ELSE
IXMODEB_ll = IIUB_ll
END IF
!JUAN Z_SPLITTING
!
!
DO JI = 1,IXMODE_ll
ZEIGENX_ll(JI) = - ( 2. *SIN (0.5*REAL(JI-1)*ZGWNX ) / PDXHATM )**2
END DO
END SELECT
!
!* 7.1.2 compute the eventual eigenvalues along the y direction
!
IF (.NOT. L2D) THEN
!
! y lateral boundary conditions for three-dimensional cases
!
SELECT CASE (HLBCY(1))
! in the cyclic case, the eigenvalues are the same for two following JN values:
! it corresponds to the real and complex parts of the FFT result
!
CASE('CYCL') ! 3D cyclic case
IYMODE_ll = IJMAX_ll+2*JPHEXT ! +2
IYMODEY_ll = IJUY_ll
IYMODEB_ll = IJUB_ll !JUAN Z_SPLITTING
!
DO JJ = 1,IYMODE_ll
DO JI = 1,IXMODE_ll
ZEIGEN_ll(JI,JJ) = ZEIGENX_ll(JI) - &
( 2.* SIN ( (JJ-1)/2*ZGWNY ) / PDYHATM )**2
END DO
END DO
!
CASE DEFAULT ! 3D non-cyclic cases
IYMODE_ll = IJMAX_ll
IYMODEY_ll = IJUY_ll - 2*JPHEXT ! -2
IYMODEB_ll = IJUB_ll - 2*JPHEXT ! -2 JUAN Z_SPLITTING
!
DO JJ = 1,IYMODE_ll
DO JI = 1,IXMODE_ll
ZEIGEN_ll(JI,JJ) = ZEIGENX_ll(JI) - ( 2.* SIN (0.5*REAL(JJ-1)*ZGWNY ) / &
PDYHATM )**2
END DO
END DO
!
END SELECT
ELSE
!
! copy the x eigenvalue array in a 2D array for a 2D case
!
IYMODE_ll = 1
IYMODEY_ll = 1
ZEIGEN_ll(1:IXMODE_ll,1)=ZEIGENX_ll(1:IXMODE_ll)
!
END IF
!
DEALLOCATE(ZEIGENX_ll)
!
!CALL MPPDB_CHECK2D(ZEIGEN_ll,"TRIDZ::ZEIGEN_ll",PRECISION)
!
!
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
637
638
639
640
641
642
643
644
645
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
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
!* 7.2 compute the matrix diagonal elements
!
!
PBFY = 1.
PBFB = 1. ! JUAN Z_SLIDE
PBF_SXP2_YP1_Z = 1. ! JUAN Z_SLIDE
!
IF (L2D) THEN
DO JK= IKB,IKE
DO JJ= 1, IYMODEY_ll
DO JI= 1, IXMODEY_ll
PBFY(JI,JJ,JK) = PRHOM(JK)* ZEIGEN_ll(JI+IORXY_ll-1,JJ+IORYY_ll-1) - 0.5 * &
( ( PRHOM(JK-1) + PRHOM(JK) ) / ZDZM(JK) **2 &
+( PRHOM(JK) + PRHOM(JK+1) ) / ZDZM(JK+1)**2 )
END DO
END DO
END DO
! at the upper and lower levels PBFY is computed using the Neumann
! condition
!
PBFY(1:IXMODEY_ll,1:IYMODEY_ll,IKB-1) = -0.5 * ( PRHOM(IKB-1) + PRHOM(IKB) ) / &
ZDZM(IKB) **2
!
PBFY(1:IXMODEY_ll,1:IYMODEY_ll,IKE+1) = 0.5 * ( PRHOM(IKE) + PRHOM(IKE+1) ) / &
ZDZM(IKE+1) **2
!
ELSE
DO JK= IKB,IKE
DO JJ= 1, IYMODEY_ll
DO JI= 1, IXMODEY_ll
PBFY(JJ,JI,JK) = PRHOM(JK)* ZEIGEN_ll(JI+IORXY_ll-1,JJ+IORYY_ll-1) - 0.5 * &
( ( PRHOM(JK-1) + PRHOM(JK) ) / ZDZM(JK) **2 &
+( PRHOM(JK) + PRHOM(JK+1) ) / ZDZM(JK+1)**2 )
END DO
END DO
END DO
! at the upper and lower levels PBFY is computed using the Neumann
! condition
!
PBFY(1:IYMODEY_ll,1:IXMODEY_ll,IKB-1) = -0.5 * ( PRHOM(IKB-1) + PRHOM(IKB) ) / &
ZDZM(IKB) **2
!
PBFY(1:IYMODEY_ll,1:IXMODEY_ll,IKE+1) = 0.5 * ( PRHOM(IKE) + PRHOM(IKE+1) ) / &
ZDZM(IKE+1) **2
!
!JUAN Z_SPLITTING
!JUAN for Z splitting we need to do the vertical substitution
!JUAN in Bsplitting slides so need PBFB
DO JK= IKB,IKE
DO JJ= IJB,IJE
DO JI= IIB, IIE
PBFB(JI,JJ,JK) = PRHOM(JK)* ZEIGEN_ll(JI+IORXB_ll-IIB_ll,JJ+IORYB_ll-IJB_ll) - 0.5 * &
( ( PRHOM(JK-1) + PRHOM(JK) ) / ZDZM(JK) **2 &
+( PRHOM(JK) + PRHOM(JK+1) ) / ZDZM(JK+1)**2 )
END DO
END DO
END DO
! at the upper and lower levels PBFB is computed using the Neumann
! condition
!
PBFB(IIB:IIE,IJB:IJE,IKB-1) = -0.5 * ( PRHOM(IKB-1) + PRHOM(IKB) ) / &
ZDZM(IKB) **2
!
PBFB(IIB:IIE,IJB:IJE,IKE+1) = 0.5 * ( PRHOM(IKE) + PRHOM(IKE+1) ) / &
ZDZM(IKE+1) **2
!
IF (HLBCX(1) == 'CYCL' .AND. .NOT.(L2D) ) THEN
!JUAN
! fil unused 2 coef with NI+1 coef (lost in Z transposition elsewhere )
JI = IXMODE_ll -1
ZEIGEN_ll(2,:) = ZEIGEN_ll(JI,:)
END IF
IF (HLBCY(1) == 'CYCL' .AND. .NOT.(L2D) ) THEN
!JUAN
! fill unused (:,2,:) coef with NJ+1 coef (lost in Z transposition elsewhere )
JJ = IYMODE_ll -1
ZEIGEN_ll(:,2) = ZEIGEN_ll(:,JJ)
END IF
!
!JUAN Z_SPLITTING
!JUAN Z_SPLITTING
!JUAN for Z splitting we need to do the vertical substitution
!JUAN in _SXP2_YP1_Zsplitting slides so need PBF_SXP2_YP1_Z
DO JK=IKB,IKE
DO JJ= 1, IJU_SXP2_YP1_Z_ll
DO JI= 1, IIU_SXP2_YP1_Z_ll
PBF_SXP2_YP1_Z(JI,JJ,JK) = PRHOM(JK)* ZEIGEN_ll(JI+IORX_SXP2_YP1_Z_ll-IIB_ll,JJ+IORY_SXP2_YP1_Z_ll-IJB_ll) - 0.5 * &
( ( PRHOM(JK-1) + PRHOM(JK) ) / ZDZM(JK) **2 &
+( PRHOM(JK) + PRHOM(JK+1) ) / ZDZM(JK+1)**2 )
END DO
END DO
END DO
! at the upper and lower levels PBFB is computed using the Neumann
! condition
!
PBF_SXP2_YP1_Z(1:IIU_SXP2_YP1_Z_ll,1:IJU_SXP2_YP1_Z_ll,IKB-1) = -0.5 * ( PRHOM(IKB-1) + PRHOM(IKB) ) / &
ZDZM(IKB) **2
!
PBF_SXP2_YP1_Z(1:IIU_SXP2_YP1_Z_ll,1:IJU_SXP2_YP1_Z_ll,IKE+1) = 0.5 * ( PRHOM(IKE) + PRHOM(IKE+1) ) / &
ZDZM(IKE+1) **2
!
!JUAN Z_SPLITTING
END IF
!
! second coefficent is meaningless in cyclic case
IF (HLBCX(1) == 'CYCL' .AND. L2D .AND. SIZE(PBFY,1) .GE. 2 ) PBFY(2,:,:)=1.
IF (HLBCX(1) == 'CYCL' .AND. .NOT.(L2D) .AND. LWEST_ll(HSPLITTING='Y') .AND. SIZE(PBFY,2) .GE.2 ) &
PBFY(:,2,:)=1.
IF (HLBCY(1) == 'CYCL' .AND. .NOT.(L2D) .AND. SIZE(PBFY,1) .GE. 2 ) PBFY(2,:,:)=1.
!JUAN Z_SPLITTING
! second coefficent is meaningless in cyclic case
IF (HLBCX(1) == 'CYCL' .AND. L2D .AND. SIZE(PBFB,1) .GE. 2 ) PBFB(2,:,:)=1.
IF (HLBCX(1) == 'CYCL' .AND. .NOT.(L2D) .AND. LWEST_ll(HSPLITTING='B') .AND. SIZE(PBFB,2) .GE.2 ) &
PBFB(:,2,:)=1.
IF (HLBCY(1) == 'CYCL' .AND. .NOT.(L2D) .AND. SIZE(PBFB,1) .GE. 2 ) PBFB(2,:,:)=1.
!JUAN Z_SPLITTING
!
DEALLOCATE(ZEIGEN_ll)
!
!
!------------------------------------------------------------------------------
!* 8. INITIALIZATION OF THE TRIGS AND IFAX ARRAYS FOR THE FFT
! -------------------------------------------------------
!
! 8.1 x lateral boundary conditions
!
CALL SET99(PTRIGSX,KIFAXX,IIMAX_ll)
!
! test on the value of KIMAX: KIMAX must be factorizable as a product
! of powers of 2,3 and 5. KIFAXX(10) is equal to IIMAX if the decomposition
! is correct, then KIFAXX(1) contains the number of decomposition factors
! of KIMAX.
!
IF (KIFAXX(10) /= IIMAX_ll) THEN
WRITE(UNIT=ILUOUT,FMT="(' ERROR',/, &
&' : THE FORM OF THE FFT USED FOR THE INVERSION OF THE FLAT ',/,&
&' OPERATOR REQUIRES THAT KIMAX MUST BE FACTORIZABLE' ,/,&
& ' AS A PRODUCT OF POWERS OF 2, 3 AND 5.')")
!callabortstop
CALL CLOSE_ll(HLUOUT,IOSTAT=IRESP)
CALL ABORT
STOP
END IF
!
IF (HLBCX(1) /= 'CYCL') THEN
!
! extra trigs for shifted (co) sine transform (FFT55)
!
INN=2*(IIMAX_ll)
ZDEL=ASIN(1.0)/REAL(IIMAX_ll)
DO JI=1,IIMAX_ll
ZANGLE=REAL(JI)*ZDEL
PTRIGSX(INN+JI)=SIN(ZANGLE)
END DO
!
ENDIF
!
! 8.2 y lateral boundary conditions
!
IF (.NOT. L2D) THEN
CALL SET99(PTRIGSY,KIFAXY,IJMAX_ll)
!
! test on the value of KJMAX: KJMAX must be factorizable as a product
! of powers of 2,3 and 5. KIFAXY(10) is equal to IJMAX_ll if the decomposition
! is correct, then KIFAXX(1) contains the number of decomposition factors
! of IIMAX_ll.
!
IF (KIFAXY(10) /= IJMAX_ll) THEN
WRITE(UNIT=ILUOUT,FMT="(' ERROR',/, &
&' : THE FORM OF THE FFT USED FOR THE INVERSION OF THE FLAT ',/,&
&' OPERATOR REQUIRES THAT KJMAX MUST BE FACTORIZABLE' ,/,&
& ' AS A PRODUCT OF POWERS OF 2, 3 AND 5.')")
!callabortstop
CALL CLOSE_ll(HLUOUT,IOSTAT=IRESP)
CALL ABORT
STOP
END IF
!
!
! other cases
!
IF (HLBCY(1) /= 'CYCL') THEN
!
! extra trigs for shifted (co) sine transform
!
INN=2*(IJMAX_ll)
ZDEL=ASIN(1.0)/REAL(IJMAX_ll)
DO JJ=1,IJMAX_ll
ZANGLE=REAL(JJ)*ZDEL
PTRIGSY(INN+JJ)=SIN(ZANGLE)
END DO
!
ENDIF
!
ENDIF
!
!------------------------------------------------------------------------------
!
END SUBROUTINE TRIDZ