source: palm/trunk/SOURCE/init_pegrid.f90 @ 1062

Last change on this file since 1062 was 1057, checked in by raasch, 12 years ago

last commit documented

  • Property svn:keywords set to Id
File size: 41.7 KB
RevLine 
[1]1 SUBROUTINE init_pegrid
[1036]2
3!--------------------------------------------------------------------------------!
4! This file is part of PALM.
5!
6! PALM is free software: you can redistribute it and/or modify it under the terms
7! of the GNU General Public License as published by the Free Software Foundation,
8! either version 3 of the License, or (at your option) any later version.
9!
10! PALM is distributed in the hope that it will be useful, but WITHOUT ANY
11! WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
12! A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
13!
14! You should have received a copy of the GNU General Public License along with
15! PALM. If not, see <http://www.gnu.org/licenses/>.
16!
17! Copyright 1997-2012  Leibniz University Hannover
18!--------------------------------------------------------------------------------!
19!
[254]20! Current revisions:
[1]21! -----------------
[760]22!
[1057]23!
[668]24! Former revisions:
25! -----------------
26! $Id: init_pegrid.f90 1057 2012-11-16 15:37:40Z maronga $
27!
[1057]28! 1056 2012-11-16 15:28:04Z raasch
29! Indices for arrays n.._mg start from zero due to definition of arrays f2 and
30! p2 as automatic arrays in recursive subroutine next_mg_level
31!
[1042]32! 1041 2012-11-06 02:36:29Z raasch
33! a 2d virtual processor topology is used by default for all machines
34!
[1037]35! 1036 2012-10-22 13:43:42Z raasch
36! code put under GPL (PALM 3.9)
37!
[1004]38! 1003 2012-09-14 14:35:53Z raasch
39! subdomains must have identical size (grid matching = "match" removed)
40!
[1002]41! 1001 2012-09-13 14:08:46Z raasch
42! all actions concerning upstream-spline-method removed
43!
[979]44! 978 2012-08-09 08:28:32Z fricke
45! dirichlet/neumann and neumann/dirichlet added
46! nxlu and nysv are also calculated for inflow boundary
47!
[810]48! 809 2012-01-30 13:32:58Z maronga
49! Bugfix: replaced .AND. and .NOT. with && and ! in the preprocessor directives
50!
[808]51! 807 2012-01-25 11:53:51Z maronga
52! New cpp directive "__check" implemented which is used by check_namelist_files
53!
[781]54! 780 2011-11-10 07:16:47Z raasch
55! Bugfix for rev 778: Misplaced error message moved to the rigth place
56!
[779]57! 778 2011-11-07 14:18:25Z fricke
58! Calculation of subdomain_size now considers the number of ghost points.
59! Further coarsening on PE0 is now possible for multigrid solver if the
60! collected field has more grid points than the subdomain of an PE.
61!
[760]62! 759 2011-09-15 13:58:31Z raasch
63! calculation of number of io_blocks and the io_group to which the respective
64! PE belongs
65!
[756]66! 755 2011-08-29 09:55:16Z witha
67! 2d-decomposition is default for lcflow (ForWind cluster in Oldenburg)
68!
[723]69! 722 2011-04-11 06:21:09Z raasch
70! Bugfix: bc_lr/ns_cyc/dirrad/raddir replaced by bc_lr/ns, because variables
71!         are not yet set here; grid_level set to 0
72!
[710]73! 709 2011-03-30 09:31:40Z raasch
74! formatting adjustments
75!
[708]76! 707 2011-03-29 11:39:40Z raasch
77! bc_lr/ns replaced by bc_lr/ns_cyc/dirrad/raddir
78!
[668]79! 667 2010-12-23 12:06:00Z suehring/gryschka
[667]80! Moved determination of target_id's from init_coupling
[669]81! Determination of parameters needed for coupling (coupling_topology, ngp_a,
82! ngp_o) with different grid/processor-topology in ocean and atmosphere
[667]83! Adaption of ngp_xy, ngp_y to a dynamic number of ghost points.
84! The maximum_grid_level changed from 1 to 0. 0 is the normal grid, 1 to
85! maximum_grid_level the grids for multigrid, in which 0 and 1 are normal grids.
86! This distinction is due to reasons of data exchange and performance for the
87! normal grid and grids in poismg.
88! The definition of MPI-Vectors adapted to a dynamic numer of ghost points.
89! New MPI-Vectors for data exchange between left and right boundaries added.
90! This is due to reasons of performance (10% faster).
[77]91!
[647]92! 646 2010-12-15 13:03:52Z raasch
93! lctit is now using a 2d decomposition by default
94!
[623]95! 622 2010-12-10 08:08:13Z raasch
96! optional barriers included in order to speed up collective operations
97!
[482]98! 438 2010-02-01 04:32:43Z raasch
99! 2d-decomposition is default for Cray-XT machines
[77]100!
[392]101! 274 2009-03-26 15:11:21Z heinze
102! Output of messages replaced by message handling routine.
103!
[226]104! 206 2008-10-13 14:59:11Z raasch
105! Implementation of a MPI-1 coupling: added __parallel within the __mpi2 part
106! 2d-decomposition is default on SGI-ICE systems
107!
[198]108! 197 2008-09-16 15:29:03Z raasch
109! multigrid levels are limited by subdomains if mg_switch_to_pe0_level = -1,
110! nz is used instead nnz for calculating mg-levels
111! Collect on PE0 horizontal index bounds from all other PEs,
112! broadcast the id of the inflow PE (using the respective communicator)
113!
[139]114! 114 2007-10-10 00:03:15Z raasch
115! Allocation of wall flag arrays for multigrid solver
116!
[110]117! 108 2007-08-24 15:10:38Z letzel
118! Intercommunicator (comm_inter) and derived data type (type_xy) for
119! coupled model runs created, assign coupling_mode_remote,
120! indices nxlu and nysv are calculated (needed for non-cyclic boundary
121! conditions)
122!
[83]123! 82 2007-04-16 15:40:52Z raasch
124! Cpp-directive lcmuk changed to intel_openmp_bug, setting of host on lcmuk by
125! cpp-directive removed
126!
[77]127! 75 2007-03-22 09:54:05Z raasch
[73]128! uxrp, vynp eliminated,
[75]129! dirichlet/neumann changed to dirichlet/radiation, etc.,
130! poisfft_init is only called if fft-solver is switched on
[1]131!
[3]132! RCS Log replace by Id keyword, revision history cleaned up
133!
[1]134! Revision 1.28  2006/04/26 13:23:32  raasch
135! lcmuk does not understand the !$ comment so a cpp-directive is required
136!
137! Revision 1.1  1997/07/24 11:15:09  raasch
138! Initial revision
139!
140!
141! Description:
142! ------------
143! Determination of the virtual processor topology (if not prescribed by the
144! user)and computation of the grid point number and array bounds of the local
145! domains.
146!------------------------------------------------------------------------------!
147
148    USE control_parameters
149    USE fft_xy
[163]150    USE grid_variables
[1]151    USE indices
152    USE pegrid
153    USE poisfft_mod
154    USE poisfft_hybrid_mod
155    USE statistics
156    USE transpose_indices
157
158
[667]159
[1]160    IMPLICIT NONE
161
[778]162    INTEGER ::  i, id_inflow_l, id_recycling_l, ind(5), j, k,                &
[151]163                maximum_grid_level_l, mg_switch_to_pe0_level_l, mg_levels_x, &
164                mg_levels_y, mg_levels_z, nnx_y, nnx_z, nny_x, nny_z, nnz_x, &
165                nnz_y, numproc_sqr, nx_total, nxl_l, nxr_l, nyn_l, nys_l,    &
[778]166                nzb_l, nzt_l, omp_get_num_threads
[1]167
168    INTEGER, DIMENSION(:), ALLOCATABLE ::  ind_all, nxlf, nxrf, nynf, nysf
169
[667]170    INTEGER, DIMENSION(2) :: pdims_remote
171
[1]172    LOGICAL ::  found
173
174!
175!-- Get the number of OpenMP threads
176    !$OMP PARALLEL
[82]177#if defined( __intel_openmp_bug )
[1]178    threads_per_task = omp_get_num_threads()
179#else
180!$  threads_per_task = omp_get_num_threads()
181#endif
182    !$OMP END PARALLEL
183
184
185#if defined( __parallel )
[667]186
[1]187!
188!-- Determine the processor topology or check it, if prescribed by the user
189    IF ( npex == -1  .AND.  npey == -1 )  THEN
190
191!
192!--    Automatic determination of the topology
[1041]193       numproc_sqr = SQRT( REAL( numprocs ) )
194       pdims(1)    = MAX( numproc_sqr , 1 )
195       DO  WHILE ( MOD( numprocs , pdims(1) ) /= 0 )
196          pdims(1) = pdims(1) - 1
197       ENDDO
198       pdims(2) = numprocs / pdims(1)
[1]199
200    ELSEIF ( npex /= -1  .AND.  npey /= -1 )  THEN
201
202!
203!--    Prescribed by user. Number of processors on the prescribed topology
204!--    must be equal to the number of PEs available to the job
205       IF ( ( npex * npey ) /= numprocs )  THEN
[274]206          WRITE( message_string, * ) 'number of PEs of the prescribed ',      & 
207                 'topology (', npex*npey,') does not match & the number of ', & 
208                 'PEs available to the job (', numprocs, ')'
[254]209          CALL message( 'init_pegrid', 'PA0221', 1, 2, 0, 6, 0 )
[1]210       ENDIF
211       pdims(1) = npex
212       pdims(2) = npey
213
214    ELSE
215!
216!--    If the processor topology is prescribed by the user, the number of
217!--    PEs must be given in both directions
[274]218       message_string = 'if the processor topology is prescribed by the, ' //  &
219                   ' user& both values of "npex" and "npey" must be given ' // &
220                   'in the &NAMELIST-parameter file'
[254]221       CALL message( 'init_pegrid', 'PA0222', 1, 2, 0, 6, 0 )
[1]222
223    ENDIF
224
225!
226!-- The hybrid solver can only be used in case of a 1d-decomposition along x
227    IF ( pdims(2) /= 1  .AND.  psolver == 'poisfft_hybrid' )  THEN
[254]228       message_string = 'psolver = "poisfft_hybrid" can only be' // &
229                        '& used in case of a 1d-decomposition along x'
230       CALL message( 'init_pegrid', 'PA0223', 1, 2, 0, 6, 0 )
[1]231    ENDIF
232
233!
[622]234!-- For communication speedup, set barriers in front of collective
235!-- communications by default on SGI-type systems
236    IF ( host(3:5) == 'sgi' )  collective_wait = .TRUE.
237
238!
[1]239!-- If necessary, set horizontal boundary conditions to non-cyclic
[722]240    IF ( bc_lr /= 'cyclic' )  cyclic(1) = .FALSE.
241    IF ( bc_ns /= 'cyclic' )  cyclic(2) = .FALSE.
[1]242
[807]243
[809]244#if ! defined( __check)
[1]245!
246!-- Create the virtual processor grid
247    CALL MPI_CART_CREATE( comm_palm, ndim, pdims, cyclic, reorder, &
248                          comm2d, ierr )
249    CALL MPI_COMM_RANK( comm2d, myid, ierr )
250    WRITE (myid_char,'(''_'',I4.4)')  myid
251
252    CALL MPI_CART_COORDS( comm2d, myid, ndim, pcoord, ierr )
253    CALL MPI_CART_SHIFT( comm2d, 0, 1, pleft, pright, ierr )
254    CALL MPI_CART_SHIFT( comm2d, 1, 1, psouth, pnorth, ierr )
255
256!
257!-- Determine sub-topologies for transpositions
258!-- Transposition from z to x:
259    remain_dims(1) = .TRUE.
260    remain_dims(2) = .FALSE.
261    CALL MPI_CART_SUB( comm2d, remain_dims, comm1dx, ierr )
262    CALL MPI_COMM_RANK( comm1dx, myidx, ierr )
263!
264!-- Transposition from x to y
265    remain_dims(1) = .FALSE.
266    remain_dims(2) = .TRUE.
267    CALL MPI_CART_SUB( comm2d, remain_dims, comm1dy, ierr )
268    CALL MPI_COMM_RANK( comm1dy, myidy, ierr )
269
[807]270#endif
[1]271
272!
[1003]273!-- Calculate array bounds along x-direction for every PE.
[1]274    ALLOCATE( nxlf(0:pdims(1)-1), nxrf(0:pdims(1)-1), nynf(0:pdims(2)-1), &
[1003]275              nysf(0:pdims(2)-1) )
[1]276
[1003]277    IF ( MOD( nx+1 , pdims(1) ) /= 0 )  THEN
[274]278       WRITE( message_string, * ) 'x-direction: gridpoint number (',nx+1,') ',&
279                               'is not an& integral divisor of the number ',  &
280                               'processors (', pdims(1),')'
[254]281       CALL message( 'init_pegrid', 'PA0225', 1, 2, 0, 6, 0 )
[1]282    ELSE
[1003]283       nnx  = ( nx + 1 ) / pdims(1)
[1]284       IF ( nnx*pdims(1) - ( nx + 1) > nnx )  THEN
[274]285          WRITE( message_string, * ) 'x-direction: nx does not match the',    & 
286                       'requirements given by the number of PEs &used',       &
287                       '& please use nx = ', nx - ( pdims(1) - ( nnx*pdims(1) &
288                                   - ( nx + 1 ) ) ), ' instead of nx =', nx
[254]289          CALL message( 'init_pegrid', 'PA0226', 1, 2, 0, 6, 0 )
[1]290       ENDIF
291    ENDIF   
292
293!
294!-- Left and right array bounds, number of gridpoints
295    DO  i = 0, pdims(1)-1
296       nxlf(i)   = i * nnx
297       nxrf(i)   = ( i + 1 ) * nnx - 1
298    ENDDO
299
300!
301!-- Calculate array bounds in y-direction for every PE.
[1003]302    IF ( MOD( ny+1 , pdims(2) ) /= 0 )  THEN
[274]303       WRITE( message_string, * ) 'y-direction: gridpoint number (',ny+1,') ', &
304                           'is not an& integral divisor of the number of',     &
305                           'processors (', pdims(2),')'
[254]306       CALL message( 'init_pegrid', 'PA0227', 1, 2, 0, 6, 0 )
[1]307    ELSE
[1003]308       nny  = ( ny + 1 ) / pdims(2)
[1]309       IF ( nny*pdims(2) - ( ny + 1) > nny )  THEN
[274]310          WRITE( message_string, * ) 'y-direction: ny does not match the',    &
311                       'requirements given by the number of PEs &used ',      &
312                       '& please use ny = ', ny - ( pdims(2) - ( nnx*pdims(2) &
[254]313                                     - ( ny + 1 ) ) ), ' instead of ny =', ny
314          CALL message( 'init_pegrid', 'PA0228', 1, 2, 0, 6, 0 )
[1]315       ENDIF
316    ENDIF   
317
318!
319!-- South and north array bounds
320    DO  j = 0, pdims(2)-1
321       nysf(j)   = j * nny
322       nynf(j)   = ( j + 1 ) * nny - 1
323    ENDDO
324
325!
326!-- Local array bounds of the respective PEs
[1003]327    nxl = nxlf(pcoord(1))
328    nxr = nxrf(pcoord(1))
329    nys = nysf(pcoord(2))
330    nyn = nynf(pcoord(2))
331    nzb = 0
332    nzt = nz
333    nnz = nz
[1]334
335!
[707]336!-- Set switches to define if the PE is situated at the border of the virtual
337!-- processor grid
338    IF ( nxl == 0 )   left_border_pe  = .TRUE.
339    IF ( nxr == nx )  right_border_pe = .TRUE.
340    IF ( nys == 0 )   south_border_pe = .TRUE.
341    IF ( nyn == ny )  north_border_pe = .TRUE.
342
343!
[1]344!-- Calculate array bounds and gridpoint numbers for the transposed arrays
345!-- (needed in the pressure solver)
346!-- For the transposed arrays, cyclic boundaries as well as top and bottom
347!-- boundaries are omitted, because they are obstructive to the transposition
348
349!
350!-- 1. transposition  z --> x
[1001]351!-- This transposition is not neccessary in case of a 1d-decomposition along x
352    IF ( pdims(2) /= 1 )  THEN
[1]353
[1003]354       nys_x = nys
355       nyn_x = nyn
356       nny_x = nny
357       IF ( MOD( nz , pdims(1) ) /= 0 )  THEN
[274]358          WRITE( message_string, * ) 'transposition z --> x:',                &
359                       '&nz=',nz,' is not an integral divisior of pdims(1)=', &
360                                                                   pdims(1)
[254]361          CALL message( 'init_pegrid', 'PA0230', 1, 2, 0, 6, 0 )
[1]362       ENDIF
[1003]363       nnz_x = nz / pdims(1)
364       nzb_x = 1 + myidx * nnz_x
365       nzt_x = ( myidx + 1 ) * nnz_x
[1]366       sendrecvcount_zx = nnx * nny * nnz_x
367
[181]368    ELSE
369!
370!---   Setting of dummy values because otherwise variables are undefined in
371!---   the next step  x --> y
372!---   WARNING: This case has still to be clarified!!!!!!!!!!!!
[1003]373       nnz_x = 1
374       nzb_x = 1
375       nzt_x = 1
376       nny_x = nny
[181]377
[1]378    ENDIF
379
380!
381!-- 2. transposition  x --> y
[1003]382    nnz_y = nnz_x
383    nzb_y = nzb_x
384    nzt_y = nzt_x
385    IF ( MOD( nx+1 , pdims(2) ) /= 0 )  THEN
[274]386       WRITE( message_string, * ) 'transposition x --> y:',                &
387                         '&nx+1=',nx+1,' is not an integral divisor of ',&
388                         'pdims(2)=',pdims(2)
[254]389       CALL message( 'init_pegrid', 'PA0231', 1, 2, 0, 6, 0 )
[1]390    ENDIF
[1003]391    nnx_y = (nx+1) / pdims(2)
[1]392    nxl_y = myidy * nnx_y
[1003]393    nxr_y = ( myidy + 1 ) * nnx_y - 1
[1]394    sendrecvcount_xy = nnx_y * nny_x * nnz_y
395
396!
397!-- 3. transposition  y --> z  (ELSE:  x --> y  in case of 1D-decomposition
398!-- along x)
[1001]399    IF ( pdims(2) /= 1 )  THEN
[1]400!
401!--    y --> z
402!--    This transposition is not neccessary in case of a 1d-decomposition
403!--    along x, except that the uptream-spline method is switched on
[1003]404       nnx_z = nnx_y
405       nxl_z = nxl_y
406       nxr_z = nxr_y
407       IF ( MOD( ny+1 , pdims(1) ) /= 0 )  THEN
[274]408          WRITE( message_string, * ) 'transposition y --> z:',            &
409                            '& ny+1=',ny+1,' is not an integral divisor of ',&
410                            'pdims(1)=',pdims(1)
[254]411          CALL message( 'init_pegrid', 'PA0232', 1, 2, 0, 6, 0 )
[1]412       ENDIF
[1003]413       nny_z = (ny+1) / pdims(1)
414       nys_z = myidx * nny_z
415       nyn_z = ( myidx + 1 ) * nny_z - 1
[1]416       sendrecvcount_yz = nnx_y * nny_z * nnz_y
417
418    ELSE
419!
420!--    x --> y. This condition must be fulfilled for a 1D-decomposition along x
[1003]421       IF ( MOD( ny+1 , pdims(1) ) /= 0 )  THEN
[274]422          WRITE( message_string, * ) 'transposition x --> y:',               &
423                            '& ny+1=',ny+1,' is not an integral divisor of ',&
424                            'pdims(1)=',pdims(1)
[254]425          CALL message( 'init_pegrid', 'PA0233', 1, 2, 0, 6, 0 )
[1]426       ENDIF
427
428    ENDIF
429
430!
431!-- Indices for direct transpositions z --> y (used for calculating spectra)
432    IF ( dt_dosp /= 9999999.9 )  THEN
[1003]433       IF ( MOD( nz, pdims(2) ) /= 0 )  THEN
[274]434          WRITE( message_string, * ) 'direct transposition z --> y (needed ', &
435                    'for spectra):& nz=',nz,' is not an integral divisor of ',&
436                    'pdims(2)=',pdims(2)
[254]437          CALL message( 'init_pegrid', 'PA0234', 1, 2, 0, 6, 0 )
[1]438       ELSE
[1003]439          nxl_yd = nxl
440          nxr_yd = nxr
441          nzb_yd = 1 + myidy * ( nz / pdims(2) )
442          nzt_yd = ( myidy + 1 ) * ( nz / pdims(2) )
443          sendrecvcount_zyd = nnx * nny * ( nz / pdims(2) )
[1]444       ENDIF
445    ENDIF
446
447!
448!-- Indices for direct transpositions y --> x (they are only possible in case
449!-- of a 1d-decomposition along x)
450    IF ( pdims(2) == 1 )  THEN
[1003]451       nny_x = nny / pdims(1)
452       nys_x = myid * nny_x
453       nyn_x = ( myid + 1 ) * nny_x - 1
454       nzb_x = 1
455       nzt_x = nz
456       sendrecvcount_xy = nnx * nny_x * nz
[1]457    ENDIF
458
459!
460!-- Indices for direct transpositions x --> y (they are only possible in case
461!-- of a 1d-decomposition along y)
462    IF ( pdims(1) == 1 )  THEN
[1003]463       nnx_y = nnx / pdims(2)
464       nxl_y = myid * nnx_y
465       nxr_y = ( myid + 1 ) * nnx_y - 1
466       nzb_y = 1
467       nzt_y = nz
468       sendrecvcount_xy = nnx_y * nny * nz
[1]469    ENDIF
470
471!
472!-- Arrays for storing the array bounds are needed any more
473    DEALLOCATE( nxlf , nxrf , nynf , nysf )
474
[807]475
[809]476#if ! defined( __check)
[145]477!
478!-- Collect index bounds from other PEs (to be written to restart file later)
479    ALLOCATE( hor_index_bounds(4,0:numprocs-1) )
480
481    IF ( myid == 0 )  THEN
482
483       hor_index_bounds(1,0) = nxl
484       hor_index_bounds(2,0) = nxr
485       hor_index_bounds(3,0) = nys
486       hor_index_bounds(4,0) = nyn
487
488!
489!--    Receive data from all other PEs
490       DO  i = 1, numprocs-1
491          CALL MPI_RECV( ibuf, 4, MPI_INTEGER, i, MPI_ANY_TAG, comm2d, status, &
492                         ierr )
493          hor_index_bounds(:,i) = ibuf(1:4)
494       ENDDO
495
496    ELSE
497!
498!--    Send index bounds to PE0
499       ibuf(1) = nxl
500       ibuf(2) = nxr
501       ibuf(3) = nys
502       ibuf(4) = nyn
503       CALL MPI_SEND( ibuf, 4, MPI_INTEGER, 0, myid, comm2d, ierr )
504
505    ENDIF
506
[807]507#endif
508
[1]509#if defined( __print )
510!
511!-- Control output
512    IF ( myid == 0 )  THEN
513       PRINT*, '*** processor topology ***'
514       PRINT*, ' '
515       PRINT*, 'myid   pcoord    left right  south north  idx idy   nxl: nxr',&
516               &'   nys: nyn'
517       PRINT*, '------------------------------------------------------------',&
518               &'-----------'
519       WRITE (*,1000)  0, pcoord(1), pcoord(2), pleft, pright, psouth, pnorth, &
520                       myidx, myidy, nxl, nxr, nys, nyn
5211000   FORMAT (I4,2X,'(',I3,',',I3,')',3X,I4,2X,I4,3X,I4,2X,I4,2X,I3,1X,I3, &
522               2(2X,I4,':',I4))
523
524!
[108]525!--    Receive data from the other PEs
[1]526       DO  i = 1,numprocs-1
527          CALL MPI_RECV( ibuf, 12, MPI_INTEGER, i, MPI_ANY_TAG, comm2d, status, &
528                         ierr )
529          WRITE (*,1000)  i, ( ibuf(j) , j = 1,12 )
530       ENDDO
531    ELSE
532
533!
534!--    Send data to PE0
535       ibuf(1) = pcoord(1); ibuf(2) = pcoord(2); ibuf(3) = pleft
536       ibuf(4) = pright; ibuf(5) = psouth; ibuf(6) = pnorth; ibuf(7) = myidx
537       ibuf(8) = myidy; ibuf(9) = nxl; ibuf(10) = nxr; ibuf(11) = nys
538       ibuf(12) = nyn
539       CALL MPI_SEND( ibuf, 12, MPI_INTEGER, 0, myid, comm2d, ierr )       
540    ENDIF
541#endif
542
[809]543#if defined( __parallel ) && ! defined( __check)
[102]544#if defined( __mpi2 )
545!
546!-- In case of coupled runs, get the port name on PE0 of the atmosphere model
547!-- and pass it to PE0 of the ocean model
548    IF ( myid == 0 )  THEN
549
550       IF ( coupling_mode == 'atmosphere_to_ocean' )  THEN
551
552          CALL MPI_OPEN_PORT( MPI_INFO_NULL, port_name, ierr )
[108]553
[102]554          CALL MPI_PUBLISH_NAME( 'palm_coupler', MPI_INFO_NULL, port_name, &
555                                 ierr )
[108]556
557!
[104]558!--       Write a flag file for the ocean model and the other atmosphere
559!--       processes.
560!--       There seems to be a bug in MPICH2 which causes hanging processes
561!--       in case that execution of LOOKUP_NAME is continued too early
562!--       (i.e. before the port has been created)
563          OPEN( 90, FILE='COUPLING_PORT_OPENED', FORM='FORMATTED' )
564          WRITE ( 90, '(''TRUE'')' )
565          CLOSE ( 90 )
[102]566
567       ELSEIF ( coupling_mode == 'ocean_to_atmosphere' )  THEN
568
[104]569!
570!--       Continue only if the atmosphere model has created the port.
571!--       There seems to be a bug in MPICH2 which causes hanging processes
572!--       in case that execution of LOOKUP_NAME is continued too early
573!--       (i.e. before the port has been created)
574          INQUIRE( FILE='COUPLING_PORT_OPENED', EXIST=found )
575          DO WHILE ( .NOT. found )
576             INQUIRE( FILE='COUPLING_PORT_OPENED', EXIST=found )
577          ENDDO
578
[102]579          CALL MPI_LOOKUP_NAME( 'palm_coupler', MPI_INFO_NULL, port_name, ierr )
580
581       ENDIF
582
583    ENDIF
584
585!
586!-- In case of coupled runs, establish the connection between the atmosphere
587!-- and the ocean model and define the intercommunicator (comm_inter)
588    CALL MPI_BARRIER( comm2d, ierr )
589    IF ( coupling_mode == 'atmosphere_to_ocean' )  THEN
590
591       CALL MPI_COMM_ACCEPT( port_name, MPI_INFO_NULL, 0, MPI_COMM_WORLD, &
592                             comm_inter, ierr )
[108]593       coupling_mode_remote = 'ocean_to_atmosphere'
594
[102]595    ELSEIF ( coupling_mode == 'ocean_to_atmosphere' )  THEN
596
597       CALL MPI_COMM_CONNECT( port_name, MPI_INFO_NULL, 0, MPI_COMM_WORLD, &
598                              comm_inter, ierr )
[108]599       coupling_mode_remote = 'atmosphere_to_ocean'
600
[102]601    ENDIF
[206]602#endif
[102]603
[667]604!
[709]605!-- Determine the number of ghost point layers
606    IF ( scalar_advec == 'ws-scheme' .OR. momentum_advec == 'ws-scheme' )  THEN
[667]607       nbgp = 3
608    ELSE
609       nbgp = 1
[709]610    ENDIF 
[667]611
[102]612!
[709]613!-- Create a new MPI derived datatype for the exchange of surface (xy) data,
614!-- which is needed for coupled atmosphere-ocean runs.
615!-- First, calculate number of grid points of an xy-plane.
[667]616    ngp_xy  = ( nxr - nxl + 1 + 2 * nbgp ) * ( nyn - nys + 1 + 2 * nbgp )
[102]617    CALL MPI_TYPE_VECTOR( ngp_xy, 1, nzt-nzb+2, MPI_REAL, type_xy, ierr )
618    CALL MPI_TYPE_COMMIT( type_xy, ierr )
[667]619
[709]620    IF ( TRIM( coupling_mode ) /= 'uncoupled' )  THEN
[667]621   
622!
623!--    Pass the number of grid points of the atmosphere model to
624!--    the ocean model and vice versa
625       IF ( coupling_mode == 'atmosphere_to_ocean' )  THEN
626
627          nx_a = nx
628          ny_a = ny
629
[709]630          IF ( myid == 0 )  THEN
631
632             CALL MPI_SEND( nx_a, 1, MPI_INTEGER, numprocs, 1, comm_inter,  &
633                            ierr )
634             CALL MPI_SEND( ny_a, 1, MPI_INTEGER, numprocs, 2, comm_inter,  &
635                            ierr )
636             CALL MPI_SEND( pdims, 2, MPI_INTEGER, numprocs, 3, comm_inter, &
637                            ierr )
638             CALL MPI_RECV( nx_o, 1, MPI_INTEGER, numprocs, 4, comm_inter,  &
639                            status, ierr )
640             CALL MPI_RECV( ny_o, 1, MPI_INTEGER, numprocs, 5, comm_inter,  &
641                            status, ierr )
642             CALL MPI_RECV( pdims_remote, 2, MPI_INTEGER, numprocs, 6,      &
[667]643                            comm_inter, status, ierr )
644          ENDIF
645
[709]646          CALL MPI_BCAST( nx_o, 1, MPI_INTEGER, 0, comm2d, ierr )
647          CALL MPI_BCAST( ny_o, 1, MPI_INTEGER, 0, comm2d, ierr ) 
648          CALL MPI_BCAST( pdims_remote, 2, MPI_INTEGER, 0, comm2d, ierr )
[667]649       
650       ELSEIF ( coupling_mode == 'ocean_to_atmosphere' )  THEN
651
652          nx_o = nx
653          ny_o = ny 
654
655          IF ( myid == 0 ) THEN
[709]656
657             CALL MPI_RECV( nx_a, 1, MPI_INTEGER, 0, 1, comm_inter, status, &
658                            ierr )
659             CALL MPI_RECV( ny_a, 1, MPI_INTEGER, 0, 2, comm_inter, status, &
660                            ierr )
661             CALL MPI_RECV( pdims_remote, 2, MPI_INTEGER, 0, 3, comm_inter, &
662                            status, ierr )
663             CALL MPI_SEND( nx_o, 1, MPI_INTEGER, 0, 4, comm_inter, ierr )
664             CALL MPI_SEND( ny_o, 1, MPI_INTEGER, 0, 5, comm_inter, ierr )
665             CALL MPI_SEND( pdims, 2, MPI_INTEGER, 0, 6, comm_inter, ierr )
[667]666          ENDIF
667
668          CALL MPI_BCAST( nx_a, 1, MPI_INTEGER, 0, comm2d, ierr)
669          CALL MPI_BCAST( ny_a, 1, MPI_INTEGER, 0, comm2d, ierr) 
670          CALL MPI_BCAST( pdims_remote, 2, MPI_INTEGER, 0, comm2d, ierr) 
671
672       ENDIF
673 
[709]674       ngp_a = ( nx_a+1 + 2 * nbgp ) * ( ny_a+1 + 2 * nbgp )
675       ngp_o = ( nx_o+1 + 2 * nbgp ) * ( ny_o+1 + 2 * nbgp )
[667]676
677!
[709]678!--    Determine if the horizontal grid and the number of PEs in ocean and
679!--    atmosphere is same or not
680       IF ( nx_o == nx_a  .AND.  ny_o == ny_a  .AND.  &
[667]681            pdims(1) == pdims_remote(1) .AND. pdims(2) == pdims_remote(2) ) &
682       THEN
683          coupling_topology = 0
684       ELSE
685          coupling_topology = 1
686       ENDIF 
687
688!
689!--    Determine the target PEs for the exchange between ocean and
690!--    atmosphere (comm2d)
[709]691       IF ( coupling_topology == 0 )  THEN
692!
693!--       In case of identical topologies, every atmosphere PE has exactly one
694!--       ocean PE counterpart and vice versa
695          IF ( TRIM( coupling_mode ) == 'atmosphere_to_ocean' ) THEN
[667]696             target_id = myid + numprocs
697          ELSE
698             target_id = myid 
699          ENDIF
700
701       ELSE
702!
703!--       In case of nonequivalent topology in ocean and atmosphere only for
704!--       PE0 in ocean and PE0 in atmosphere a target_id is needed, since
[709]705!--       data echxchange between ocean and atmosphere will be done only
706!--       between these PEs.   
707          IF ( myid == 0 )  THEN
708
709             IF ( TRIM( coupling_mode ) == 'atmosphere_to_ocean' )  THEN
[667]710                target_id = numprocs 
711             ELSE
712                target_id = 0
713             ENDIF
[709]714
[667]715          ENDIF
[709]716
[667]717       ENDIF
718
719    ENDIF
720
721
[102]722#endif
723
[1]724#else
725
726!
727!-- Array bounds when running on a single PE (respectively a non-parallel
728!-- machine)
[1003]729    nxl = 0
730    nxr = nx
731    nnx = nxr - nxl + 1
732    nys = 0
733    nyn = ny
734    nny = nyn - nys + 1
735    nzb = 0
736    nzt = nz
737    nnz = nz
[1]738
[145]739    ALLOCATE( hor_index_bounds(4,0:0) )
740    hor_index_bounds(1,0) = nxl
741    hor_index_bounds(2,0) = nxr
742    hor_index_bounds(3,0) = nys
743    hor_index_bounds(4,0) = nyn
744
[1]745!
746!-- Array bounds for the pressure solver (in the parallel code, these bounds
747!-- are the ones for the transposed arrays)
[1003]748    nys_x = nys
749    nyn_x = nyn
750    nzb_x = nzb + 1
751    nzt_x = nzt
[1]752
[1003]753    nxl_y = nxl
754    nxr_y = nxr
755    nzb_y = nzb + 1
756    nzt_y = nzt
[1]757
[1003]758    nxl_z = nxl
759    nxr_z = nxr
760    nys_z = nys
761    nyn_z = nyn
[1]762
763#endif
764
765!
766!-- Calculate number of grid levels necessary for the multigrid poisson solver
767!-- as well as the gridpoint indices on each level
768    IF ( psolver == 'multigrid' )  THEN
769
770!
771!--    First calculate number of possible grid levels for the subdomains
772       mg_levels_x = 1
773       mg_levels_y = 1
774       mg_levels_z = 1
775
776       i = nnx
777       DO WHILE ( MOD( i, 2 ) == 0  .AND.  i /= 2 )
778          i = i / 2
779          mg_levels_x = mg_levels_x + 1
780       ENDDO
781
782       j = nny
783       DO WHILE ( MOD( j, 2 ) == 0  .AND.  j /= 2 )
784          j = j / 2
785          mg_levels_y = mg_levels_y + 1
786       ENDDO
787
[181]788       k = nz    ! do not use nnz because it might be > nz due to transposition
789                 ! requirements
[1]790       DO WHILE ( MOD( k, 2 ) == 0  .AND.  k /= 2 )
791          k = k / 2
792          mg_levels_z = mg_levels_z + 1
793       ENDDO
794
795       maximum_grid_level = MIN( mg_levels_x, mg_levels_y, mg_levels_z )
796
797!
798!--    Find out, if the total domain allows more levels. These additional
[709]799!--    levels are identically processed on all PEs.
[197]800       IF ( numprocs > 1  .AND.  mg_switch_to_pe0_level /= -1 )  THEN
[709]801
[1]802          IF ( mg_levels_z > MIN( mg_levels_x, mg_levels_y ) )  THEN
[709]803
[1]804             mg_switch_to_pe0_level_l = maximum_grid_level
805
806             mg_levels_x = 1
807             mg_levels_y = 1
808
809             i = nx+1
810             DO WHILE ( MOD( i, 2 ) == 0  .AND.  i /= 2 )
811                i = i / 2
812                mg_levels_x = mg_levels_x + 1
813             ENDDO
814
815             j = ny+1
816             DO WHILE ( MOD( j, 2 ) == 0  .AND.  j /= 2 )
817                j = j / 2
818                mg_levels_y = mg_levels_y + 1
819             ENDDO
820
821             maximum_grid_level_l = MIN( mg_levels_x, mg_levels_y, mg_levels_z )
822
823             IF ( maximum_grid_level_l > mg_switch_to_pe0_level_l )  THEN
824                mg_switch_to_pe0_level_l = maximum_grid_level_l - &
825                                           mg_switch_to_pe0_level_l + 1
826             ELSE
827                mg_switch_to_pe0_level_l = 0
828             ENDIF
[709]829
[1]830          ELSE
831             mg_switch_to_pe0_level_l = 0
832             maximum_grid_level_l = maximum_grid_level
[709]833
[1]834          ENDIF
835
836!
837!--       Use switch level calculated above only if it is not pre-defined
838!--       by user
839          IF ( mg_switch_to_pe0_level == 0 )  THEN
840             IF ( mg_switch_to_pe0_level_l /= 0 )  THEN
841                mg_switch_to_pe0_level = mg_switch_to_pe0_level_l
842                maximum_grid_level     = maximum_grid_level_l
843             ENDIF
844
845          ELSE
846!
847!--          Check pre-defined value and reset to default, if neccessary
848             IF ( mg_switch_to_pe0_level < mg_switch_to_pe0_level_l  .OR.  &
849                  mg_switch_to_pe0_level >= maximum_grid_level_l )  THEN
[254]850                message_string = 'mg_switch_to_pe0_level ' // &
851                                 'out of range and reset to default (=0)'
852                CALL message( 'init_pegrid', 'PA0235', 0, 1, 0, 6, 0 )
[1]853                mg_switch_to_pe0_level = 0
854             ELSE
855!
856!--             Use the largest number of possible levels anyway and recalculate
857!--             the switch level to this largest number of possible values
858                maximum_grid_level = maximum_grid_level_l
859
860             ENDIF
[709]861
[1]862          ENDIF
863
864       ENDIF
865
[1056]866       ALLOCATE( grid_level_count(maximum_grid_level),                       &
867                 nxl_mg(0:maximum_grid_level), nxr_mg(0:maximum_grid_level), &
868                 nyn_mg(0:maximum_grid_level), nys_mg(0:maximum_grid_level), &
869                 nzt_mg(0:maximum_grid_level) )
[1]870
871       grid_level_count = 0
[1056]872!
873!--    Index zero required as dummy due to definition of arrays f2 and p2 in
874!--    recursive subroutine next_mg_level
875       nxl_mg(0) = 0; nxr_mg(0) = 0; nyn_mg(0) = 0; nys_mg(0) = 0; nzt_mg(0) = 0
[778]876
[1]877       nxl_l = nxl; nxr_l = nxr; nys_l = nys; nyn_l = nyn; nzt_l = nzt
878
879       DO  i = maximum_grid_level, 1 , -1
880
881          IF ( i == mg_switch_to_pe0_level )  THEN
[809]882#if defined( __parallel ) && ! defined( __check )
[1]883!
884!--          Save the grid size of the subdomain at the switch level, because
885!--          it is needed in poismg.
886             ind(1) = nxl_l; ind(2) = nxr_l
887             ind(3) = nys_l; ind(4) = nyn_l
888             ind(5) = nzt_l
889             ALLOCATE( ind_all(5*numprocs), mg_loc_ind(5,0:numprocs-1) )
890             CALL MPI_ALLGATHER( ind, 5, MPI_INTEGER, ind_all, 5, &
891                                 MPI_INTEGER, comm2d, ierr )
892             DO  j = 0, numprocs-1
893                DO  k = 1, 5
894                   mg_loc_ind(k,j) = ind_all(k+j*5)
895                ENDDO
896             ENDDO
897             DEALLOCATE( ind_all )
898!
[709]899!--          Calculate the grid size of the total domain
[1]900             nxr_l = ( nxr_l-nxl_l+1 ) * pdims(1) - 1
901             nxl_l = 0
902             nyn_l = ( nyn_l-nys_l+1 ) * pdims(2) - 1
903             nys_l = 0
904!
905!--          The size of this gathered array must not be larger than the
906!--          array tend, which is used in the multigrid scheme as a temporary
[778]907!--          array. Therefore the subdomain size of an PE is calculated and
908!--          the size of the gathered grid. These values are used in 
909!--          routines pres and poismg
910             subdomain_size = ( nxr - nxl + 2 * nbgp + 1 ) * &
911                              ( nyn - nys + 2 * nbgp + 1 ) * ( nzt - nzb + 2 )
[1]912             gathered_size  = ( nxr_l - nxl_l + 3 ) * ( nyn_l - nys_l + 3 ) * &
913                              ( nzt_l - nzb + 2 )
914
[809]915#elif ! defined ( __parallel )
[254]916             message_string = 'multigrid gather/scatter impossible ' // &
[1]917                          'in non parallel mode'
[254]918             CALL message( 'init_pegrid', 'PA0237', 1, 2, 0, 6, 0 )
[1]919#endif
920          ENDIF
921
922          nxl_mg(i) = nxl_l
923          nxr_mg(i) = nxr_l
924          nys_mg(i) = nys_l
925          nyn_mg(i) = nyn_l
926          nzt_mg(i) = nzt_l
927
928          nxl_l = nxl_l / 2 
929          nxr_l = nxr_l / 2
930          nys_l = nys_l / 2 
931          nyn_l = nyn_l / 2 
932          nzt_l = nzt_l / 2 
[778]933
[1]934       ENDDO
935
[780]936!
937!--    Temporary problem: Currently calculation of maxerror iin routine poismg crashes
938!--    if grid data are collected on PE0 already on the finest grid level.
939!--    To be solved later.
940       IF ( maximum_grid_level == mg_switch_to_pe0_level )  THEN
941          message_string = 'grid coarsening on subdomain level cannot be performed'
942          CALL message( 'poismg', 'PA0236', 1, 2, 0, 6, 0 )
943       ENDIF
944
[1]945    ELSE
946
[667]947       maximum_grid_level = 0
[1]948
949    ENDIF
950
[722]951!
952!-- Default level 0 tells exchange_horiz that all ghost planes have to be
953!-- exchanged. grid_level is adjusted in poismg, where only one ghost plane
954!-- is required.
955    grid_level = 0
[1]956
[809]957#if defined( __parallel ) && ! defined ( __check )
[1]958!
959!-- Gridpoint number for the exchange of ghost points (y-line for 2D-arrays)
[667]960    ngp_y  = nyn - nys + 1 + 2 * nbgp
[1]961
962!
[709]963!-- Define new MPI derived datatypes for the exchange of ghost points in
964!-- x- and y-direction for 2D-arrays (line)
965    CALL MPI_TYPE_VECTOR( nxr-nxl+1+2*nbgp, nbgp, ngp_y, MPI_REAL, type_x, &
966                          ierr )
[1]967    CALL MPI_TYPE_COMMIT( type_x, ierr )
[709]968    CALL MPI_TYPE_VECTOR( nxr-nxl+1+2*nbgp, nbgp, ngp_y, MPI_INTEGER, &
969                          type_x_int, ierr )
[1]970    CALL MPI_TYPE_COMMIT( type_x_int, ierr )
971
[667]972    CALL MPI_TYPE_VECTOR( nbgp, ngp_y, ngp_y, MPI_REAL, type_y, ierr )
973    CALL MPI_TYPE_COMMIT( type_y, ierr )
974    CALL MPI_TYPE_VECTOR( nbgp, ngp_y, ngp_y, MPI_INTEGER, type_y_int, ierr )
975    CALL MPI_TYPE_COMMIT( type_y_int, ierr )
976
977
[1]978!
979!-- Calculate gridpoint numbers for the exchange of ghost points along x
980!-- (yz-plane for 3D-arrays) and define MPI derived data type(s) for the
981!-- exchange of ghost points in y-direction (xz-plane).
982!-- Do these calculations for the model grid and (if necessary) also
983!-- for the coarser grid levels used in the multigrid method
[667]984    ALLOCATE ( ngp_yz(0:maximum_grid_level), type_xz(0:maximum_grid_level),&
985               type_yz(0:maximum_grid_level) )
[1]986
987    nxl_l = nxl; nxr_l = nxr; nys_l = nys; nyn_l = nyn; nzb_l = nzb; nzt_l = nzt
[709]988
[667]989!
990!-- Discern between the model grid, which needs nbgp ghost points and
991!-- grid levels for the multigrid scheme. In the latter case only one
992!-- ghost point is necessary.
[709]993!-- First definition of MPI-datatypes for exchange of ghost layers on normal
[667]994!-- grid. The following loop is needed for data exchange in poismg.f90.
995!
996!-- Determine number of grid points of yz-layer for exchange
997    ngp_yz(0) = (nzt - nzb + 2) * (nyn - nys + 1 + 2 * nbgp)
[709]998
[667]999!
[709]1000!-- Define an MPI-datatype for the exchange of left/right boundaries.
1001!-- Although data are contiguous in physical memory (which does not
1002!-- necessarily require an MPI-derived datatype), the data exchange between
1003!-- left and right PE's using the MPI-derived type is 10% faster than without.
[667]1004    CALL MPI_TYPE_VECTOR( nxr-nxl+1+2*nbgp, nbgp*(nzt-nzb+2), ngp_yz(0), &
[709]1005                          MPI_REAL, type_xz(0), ierr )
[667]1006    CALL MPI_TYPE_COMMIT( type_xz(0), ierr )
[1]1007
[709]1008    CALL MPI_TYPE_VECTOR( nbgp, ngp_yz(0), ngp_yz(0), MPI_REAL, type_yz(0), &
1009                          ierr ) 
[667]1010    CALL MPI_TYPE_COMMIT( type_yz(0), ierr )
[709]1011
[667]1012!
[709]1013!-- Definition of MPI-datatypes for multigrid method (coarser level grids)
[667]1014    IF ( psolver == 'multigrid' )  THEN
1015!   
[709]1016!--    Definition of MPI-datatyoe as above, but only 1 ghost level is used
1017       DO  i = maximum_grid_level, 1 , -1
1018
[667]1019          ngp_yz(i) = (nzt_l - nzb_l + 2) * (nyn_l - nys_l + 3)
1020
1021          CALL MPI_TYPE_VECTOR( nxr_l-nxl_l+3, nzt_l-nzb_l+2, ngp_yz(i), &
[709]1022                                MPI_REAL, type_xz(i), ierr )
[667]1023          CALL MPI_TYPE_COMMIT( type_xz(i), ierr )
[1]1024
[709]1025          CALL MPI_TYPE_VECTOR( 1, ngp_yz(i), ngp_yz(i), MPI_REAL, type_yz(i), &
1026                                ierr )
[667]1027          CALL MPI_TYPE_COMMIT( type_yz(i), ierr )
1028
1029          nxl_l = nxl_l / 2
1030          nxr_l = nxr_l / 2
1031          nys_l = nys_l / 2
1032          nyn_l = nyn_l / 2
1033          nzt_l = nzt_l / 2
[709]1034
[667]1035       ENDDO
[709]1036
1037    ENDIF
[1]1038#endif
1039
[809]1040#if defined( __parallel ) && ! defined ( __check )
[1]1041!
1042!-- Setting of flags for inflow/outflow conditions in case of non-cyclic
[106]1043!-- horizontal boundary conditions.
[1]1044    IF ( pleft == MPI_PROC_NULL )  THEN
[978]1045       IF ( bc_lr == 'dirichlet/radiation' .OR. bc_lr == 'dirichlet/neumann' )  THEN
[1]1046          inflow_l  = .TRUE.
[978]1047       ELSEIF ( bc_lr == 'radiation/dirichlet' .OR. bc_lr == 'neumann/dirichlet' )  THEN
[1]1048          outflow_l = .TRUE.
1049       ENDIF
1050    ENDIF
1051
1052    IF ( pright == MPI_PROC_NULL )  THEN
[978]1053       IF ( bc_lr == 'dirichlet/radiation' .OR. bc_lr == 'dirichlet/neumann' )  THEN
[1]1054          outflow_r = .TRUE.
[978]1055       ELSEIF ( bc_lr == 'radiation/dirichlet' .OR. bc_lr == 'neumann/dirichlet' )  THEN
[1]1056          inflow_r  = .TRUE.
1057       ENDIF
1058    ENDIF
1059
1060    IF ( psouth == MPI_PROC_NULL )  THEN
[978]1061       IF ( bc_ns == 'dirichlet/radiation' .OR. bc_ns == 'dirichlet/neumann' )  THEN
[1]1062          outflow_s = .TRUE.
[978]1063       ELSEIF ( bc_ns == 'radiation/dirichlet' .OR. bc_ns == 'neumann/dirichlet' )  THEN
[1]1064          inflow_s  = .TRUE.
1065       ENDIF
1066    ENDIF
1067
1068    IF ( pnorth == MPI_PROC_NULL )  THEN
[978]1069       IF ( bc_ns == 'dirichlet/radiation' .OR. bc_ns == 'dirichlet/neumann' )  THEN
[1]1070          inflow_n  = .TRUE.
[978]1071       ELSEIF ( bc_ns == 'radiation/dirichlet' .OR. bc_ns == 'neumann/dirichlet' )  THEN
[1]1072          outflow_n = .TRUE.
1073       ENDIF
1074    ENDIF
1075
[151]1076!
1077!-- Broadcast the id of the inflow PE
1078    IF ( inflow_l )  THEN
[163]1079       id_inflow_l = myidx
[151]1080    ELSE
1081       id_inflow_l = 0
1082    ENDIF
[622]1083    IF ( collective_wait )  CALL MPI_BARRIER( comm2d, ierr )
[151]1084    CALL MPI_ALLREDUCE( id_inflow_l, id_inflow, 1, MPI_INTEGER, MPI_SUM, &
1085                        comm1dx, ierr )
1086
[163]1087!
1088!-- Broadcast the id of the recycling plane
1089!-- WARNING: needs to be adjusted in case of inflows other than from left side!
[622]1090    IF ( ( recycling_width / dx ) >= nxl  .AND. &
1091         ( recycling_width / dx ) <= nxr )  THEN
[163]1092       id_recycling_l = myidx
1093    ELSE
1094       id_recycling_l = 0
1095    ENDIF
[622]1096    IF ( collective_wait )  CALL MPI_BARRIER( comm2d, ierr )
[163]1097    CALL MPI_ALLREDUCE( id_recycling_l, id_recycling, 1, MPI_INTEGER, MPI_SUM, &
1098                        comm1dx, ierr )
1099
[809]1100#elif ! defined ( __parallel )
[978]1101    IF ( bc_lr == 'dirichlet/radiation' .OR. bc_lr == 'dirichlet/neumann' )  THEN
[1]1102       inflow_l  = .TRUE.
1103       outflow_r = .TRUE.
[978]1104    ELSEIF ( bc_lr == 'radiation/dirichlet' .OR. bc_lr == 'neumann/dirichlet' )  THEN
[1]1105       outflow_l = .TRUE.
1106       inflow_r  = .TRUE.
1107    ENDIF
1108
[978]1109    IF ( bc_ns == 'dirichlet/radiation' .OR. bc_ns == 'dirichlet/neumann' )  THEN
[1]1110       inflow_n  = .TRUE.
1111       outflow_s = .TRUE.
[978]1112    ELSEIF ( bc_ns == 'radiation/dirichlet' .OR. bc_ns == 'neumann/dirichlet' )  THEN
[1]1113       outflow_n = .TRUE.
1114       inflow_s  = .TRUE.
1115    ENDIF
1116#endif
[807]1117
[106]1118!
[978]1119!-- At the inflow or outflow, u or v, respectively, have to be calculated for
1120!-- one more grid point.
1121    IF ( inflow_l .OR. outflow_l )  THEN
[106]1122       nxlu = nxl + 1
1123    ELSE
1124       nxlu = nxl
1125    ENDIF
[978]1126    IF ( inflow_s .OR. outflow_s )  THEN
[106]1127       nysv = nys + 1
1128    ELSE
1129       nysv = nys
1130    ENDIF
[1]1131
1132    IF ( psolver == 'poisfft_hybrid' )  THEN
1133       CALL poisfft_hybrid_ini
[75]1134    ELSEIF ( psolver == 'poisfft' )  THEN
[1]1135       CALL poisfft_init
1136    ENDIF
1137
[114]1138!
1139!-- Allocate wall flag arrays used in the multigrid solver
1140    IF ( psolver == 'multigrid' )  THEN
1141
1142       DO  i = maximum_grid_level, 1, -1
1143
1144           SELECT CASE ( i )
1145
1146              CASE ( 1 )
1147                 ALLOCATE( wall_flags_1(nzb:nzt_mg(i)+1,         &
1148                                        nys_mg(i)-1:nyn_mg(i)+1, &
1149                                        nxl_mg(i)-1:nxr_mg(i)+1) )
1150
1151              CASE ( 2 )
1152                 ALLOCATE( wall_flags_2(nzb:nzt_mg(i)+1,         &
1153                                        nys_mg(i)-1:nyn_mg(i)+1, &
1154                                        nxl_mg(i)-1:nxr_mg(i)+1) )
1155
1156              CASE ( 3 )
1157                 ALLOCATE( wall_flags_3(nzb:nzt_mg(i)+1,         &
1158                                        nys_mg(i)-1:nyn_mg(i)+1, &
1159                                        nxl_mg(i)-1:nxr_mg(i)+1) )
1160
1161              CASE ( 4 )
1162                 ALLOCATE( wall_flags_4(nzb:nzt_mg(i)+1,         &
1163                                        nys_mg(i)-1:nyn_mg(i)+1, &
1164                                        nxl_mg(i)-1:nxr_mg(i)+1) )
1165
1166              CASE ( 5 )
1167                 ALLOCATE( wall_flags_5(nzb:nzt_mg(i)+1,         &
1168                                        nys_mg(i)-1:nyn_mg(i)+1, &
1169                                        nxl_mg(i)-1:nxr_mg(i)+1) )
1170
1171              CASE ( 6 )
1172                 ALLOCATE( wall_flags_6(nzb:nzt_mg(i)+1,         &
1173                                        nys_mg(i)-1:nyn_mg(i)+1, &
1174                                        nxl_mg(i)-1:nxr_mg(i)+1) )
1175
1176              CASE ( 7 )
1177                 ALLOCATE( wall_flags_7(nzb:nzt_mg(i)+1,         &
1178                                        nys_mg(i)-1:nyn_mg(i)+1, &
1179                                        nxl_mg(i)-1:nxr_mg(i)+1) )
1180
1181              CASE ( 8 )
1182                 ALLOCATE( wall_flags_8(nzb:nzt_mg(i)+1,         &
1183                                        nys_mg(i)-1:nyn_mg(i)+1, &
1184                                        nxl_mg(i)-1:nxr_mg(i)+1) )
1185
1186              CASE ( 9 )
1187                 ALLOCATE( wall_flags_9(nzb:nzt_mg(i)+1,         &
1188                                        nys_mg(i)-1:nyn_mg(i)+1, &
1189                                        nxl_mg(i)-1:nxr_mg(i)+1) )
1190
1191              CASE ( 10 )
1192                 ALLOCATE( wall_flags_10(nzb:nzt_mg(i)+1,        &
1193                                        nys_mg(i)-1:nyn_mg(i)+1, &
1194                                        nxl_mg(i)-1:nxr_mg(i)+1) )
1195
1196              CASE DEFAULT
[254]1197                 message_string = 'more than 10 multigrid levels'
1198                 CALL message( 'init_pegrid', 'PA0238', 1, 2, 0, 6, 0 )
[114]1199
1200          END SELECT
1201
1202       ENDDO
1203
1204    ENDIF
1205
[759]1206!
1207!-- Calculate the number of groups into which parallel I/O is split.
1208!-- The default for files which are opened by all PEs (or where each
1209!-- PE opens his own independent file) is, that all PEs are doing input/output
1210!-- in parallel at the same time. This might cause performance or even more
1211!-- severe problems depending on the configuration of the underlying file
1212!-- system.
1213!-- First, set the default:
1214    IF ( maximum_parallel_io_streams == -1  .OR. &
1215         maximum_parallel_io_streams > numprocs )  THEN
1216       maximum_parallel_io_streams = numprocs
1217    ENDIF
1218
1219!
1220!-- Now calculate the number of io_blocks and the io_group to which the
1221!-- respective PE belongs. I/O of the groups is done in serial, but in parallel
1222!-- for all PEs belonging to the same group. A preliminary setting with myid
1223!-- based on MPI_COMM_WORLD has been done in parin.
1224    io_blocks = numprocs / maximum_parallel_io_streams
1225    io_group  = MOD( myid+1, io_blocks )
1226   
1227
[1]1228 END SUBROUTINE init_pegrid
Note: See TracBrowser for help on using the repository browser.