source: palm/trunk/SOURCE/exchange_horiz.f90 @ 2993

Last change on this file since 2993 was 2718, checked in by maronga, 7 years ago

deleting of deprecated files; headers updated where needed

  • Property svn:keywords set to Id
File size: 13.5 KB
RevLine 
[1682]1!> @file exchange_horiz.f90
[1320]2!------------------------------------------------------------------------------!
[2696]3! This file is part of the PALM model system.
[1036]4!
[2000]5! PALM is free software: you can redistribute it and/or modify it under the
6! terms of the GNU General Public License as published by the Free Software
7! Foundation, either version 3 of the License, or (at your option) any later
8! version.
[1036]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!
[2718]17! Copyright 1997-2018 Leibniz Universitaet Hannover
[1320]18!------------------------------------------------------------------------------!
[1036]19!
[484]20! Current revisions:
[1]21! -----------------
[1678]22!
[2119]23!
[1321]24! Former revisions:
25! -----------------
26! $Id: exchange_horiz.f90 2718 2018-01-02 08:49:38Z raasch $
[2716]27! Corrected "Former revisions" section
28!
29! 2696 2017-12-14 17:12:51Z kanani
30! Change in file header (GPL part)
[2696]31! 3D-Integer exchange on multigrid level (MS)
32!
33! 2298 2017-06-29 09:28:18Z raasch
[2298]34! sendrecv_in_background related parts removed
35!
36! 2119 2017-01-17 16:51:50Z raasch
[1321]37!
[2119]38! 2118 2017-01-17 16:38:49Z raasch
39! OpenACC directives and related code removed
40!
[2001]41! 2000 2016-08-20 18:09:15Z knoop
42! Forced header and separation lines into 80 columns
43!
[1805]44! 1804 2016-04-05 16:30:18Z maronga
45! Removed code for parameter file check (__check)
46!
[1683]47! 1682 2015-10-07 23:56:08Z knoop
48! Code annotations made doxygen readable
49!
[1678]50! 1677 2015-10-02 13:25:23Z boeske
51! Added new routine for exchange of three-dimensional integer arrays
52!
[1570]53! 1569 2015-03-12 07:54:38Z raasch
54! bugfix in background communication part
55!
[1349]56! 1348 2014-03-27 18:01:03Z raasch
[1569]57! bugfix: on_device added to ONLY-list
[1349]58!
[1345]59! 1344 2014-03-26 17:33:09Z kanani
60! Added missing parameters to ONLY-attribute
61!
[1321]62! 1320 2014-03-20 08:40:49Z raasch
[1320]63! ONLY-attribute added to USE-statements,
64! kind-parameters added to all INTEGER and REAL declaration statements,
65! kinds are defined in new module kinds,
66! revision history before 2012 removed,
67! comment fields (!:) to be used for variable explanations added to
68! all variable declaration statements
[668]69!
[1258]70! 1257 2013-11-08 15:18:40Z raasch
71! openacc loop and loop vector clauses removed
72!
[1132]73! 1128 2013-04-12 06:19:32Z raasch
74! modifications for asynchronous transfer,
75! local variables req, wait_stat are global now, and have been moved to module
76! pegrid
77!
[1114]78! 1113 2013-03-10 02:48:14Z raasch
79! GPU-porting for single-core (1PE) mode
80!
[1037]81! 1036 2012-10-22 13:43:42Z raasch
82! code put under GPL (PALM 3.9)
83!
[842]84! 841 2012-02-28 12:29:49Z maronga
85! Excluded routine from compilation of namelist_file_check
86!
[1]87! Revision 1.1  1997/07/24 11:13:29  raasch
88! Initial revision
89!
90!
91! Description:
92! ------------
[1682]93!> Exchange of lateral boundary values (parallel computers) and cyclic
94!> lateral boundary conditions, respectively.
[1]95!------------------------------------------------------------------------------!
[1682]96 SUBROUTINE exchange_horiz( ar, nbgp_local)
97 
[1]98
[1320]99    USE control_parameters,                                                    &
[1344]100        ONLY:  bc_lr, bc_lr_cyc, bc_ns, bc_ns_cyc, grid_level,                 &
[2118]101               mg_switch_to_pe0, synchronous_exchange
[1320]102               
103    USE cpulog,                                                                &
104        ONLY:  cpu_log, log_point_s
105       
106    USE indices,                                                               &
107        ONLY:  nxl, nxr, nyn, nys, nzb, nzt
108       
109    USE kinds
110   
[1]111    USE pegrid
112
113    IMPLICIT NONE
114
[841]115
[1682]116    INTEGER(iwp) ::  i           !<
117    INTEGER(iwp) ::  j           !<
118    INTEGER(iwp) ::  k           !<
119    INTEGER(iwp) ::  nbgp_local  !<
[1320]120   
121    REAL(wp), DIMENSION(nzb:nzt+1,nys-nbgp_local:nyn+nbgp_local,               &
[1682]122                        nxl-nbgp_local:nxr+nbgp_local) ::  ar  !<
[1320]123                       
[841]124
[1]125    CALL cpu_log( log_point_s(2), 'exchange_horiz', 'start' )
126
127#if defined( __parallel )
128
129!
[1128]130!-- Exchange in x-direction of lateral boundaries
[1]131    IF ( pdims(1) == 1  .OR.  mg_switch_to_pe0 )  THEN
132!
133!--    One-dimensional decomposition along y, boundary values can be exchanged
134!--    within the PE memory
[707]135       IF ( bc_lr_cyc )  THEN
[667]136          ar(:,:,nxl-nbgp_local:nxl-1) = ar(:,:,nxr-nbgp_local+1:nxr)
137          ar(:,:,nxr+1:nxr+nbgp_local) = ar(:,:,nxl:nxl+nbgp_local-1)
[1]138       ENDIF
139
140    ELSE
[75]141
[683]142       IF ( synchronous_exchange )  THEN
[1]143!
[683]144!--       Send left boundary, receive right one (synchronous)
145          CALL MPI_SENDRECV(                                                   &
[707]146              ar(nzb,nys-nbgp_local,nxl),   1, type_yz(grid_level), pleft,  0, &
147              ar(nzb,nys-nbgp_local,nxr+1), 1, type_yz(grid_level), pright, 0, &
148              comm2d, status, ierr )
[1]149!
[683]150!--       Send right boundary, receive left one (synchronous)
[1320]151          CALL MPI_SENDRECV( ar(nzb,nys-nbgp_local,nxr+1-nbgp_local), 1,       &
152                             type_yz(grid_level), pright, 1,                   &
153                             ar(nzb,nys-nbgp_local,nxl-nbgp_local), 1,         &
154                             type_yz(grid_level), pleft,  1,                   &
[707]155                             comm2d, status, ierr )
[667]156
[683]157       ELSE
[667]158
[683]159!
[2298]160!--       Asynchroneous exchange
[1128]161          IF ( send_receive == 'lr'  .OR.  send_receive == 'al' )  THEN
162
[2298]163             req(1:4)  = 0
164             req_count = 0
[683]165!
[1128]166!--          Send left boundary, receive right one (asynchronous)
167             CALL MPI_ISEND( ar(nzb,nys-nbgp_local,nxl),   1, type_yz(grid_level), &
168                             pleft, req_count, comm2d, req(req_count+1), ierr )
169             CALL MPI_IRECV( ar(nzb,nys-nbgp_local,nxr+1), 1, type_yz(grid_level), &
170                             pright, req_count, comm2d, req(req_count+2), ierr )
171!
172!--          Send right boundary, receive left one (asynchronous)
[1320]173             CALL MPI_ISEND( ar(nzb,nys-nbgp_local,nxr+1-nbgp_local), 1,       &
174                             type_yz(grid_level), pright, req_count+1, comm2d, &
[1128]175                             req(req_count+3), ierr )
[1320]176             CALL MPI_IRECV( ar(nzb,nys-nbgp_local,nxl-nbgp_local),   1,       &
177                             type_yz(grid_level), pleft,  req_count+1, comm2d, &
[1128]178                             req(req_count+4), ierr )
[667]179
[2298]180             CALL MPI_WAITALL( 4, req, wait_stat, ierr )
[75]181
[1128]182          ENDIF
183
[683]184       ENDIF
185
[1]186    ENDIF
187
188
189    IF ( pdims(2) == 1  .OR.  mg_switch_to_pe0 )  THEN
190!
191!--    One-dimensional decomposition along x, boundary values can be exchanged
192!--    within the PE memory
[707]193       IF ( bc_ns_cyc )  THEN
[667]194          ar(:,nys-nbgp_local:nys-1,:) = ar(:,nyn-nbgp_local+1:nyn,:)
195          ar(:,nyn+1:nyn+nbgp_local,:) = ar(:,nys:nys+nbgp_local-1,:)
[1]196       ENDIF
197
198    ELSE
199
[683]200       IF ( synchronous_exchange )  THEN
[1]201!
[683]202!--       Send front boundary, receive rear one (synchronous)
203          CALL MPI_SENDRECV(                                                   &
[707]204              ar(nzb,nys,nxl-nbgp_local),   1, type_xz(grid_level), psouth, 0, &
205              ar(nzb,nyn+1,nxl-nbgp_local), 1, type_xz(grid_level), pnorth, 0, &
206              comm2d, status, ierr )
[683]207!
208!--       Send rear boundary, receive front one (synchronous)
[1320]209          CALL MPI_SENDRECV( ar(nzb,nyn-nbgp_local+1,nxl-nbgp_local), 1,       &
210                             type_xz(grid_level), pnorth, 1,                   &
211                             ar(nzb,nys-nbgp_local,nxl-nbgp_local),   1,       &
212                             type_xz(grid_level), psouth, 1,                   &
[707]213                             comm2d, status, ierr )
[667]214
[683]215       ELSE
216
[1]217!
[2298]218!--       Asynchroneous exchange
[1569]219          IF ( send_receive == 'ns'  .OR.  send_receive == 'al' )  THEN
[1128]220
[2298]221             req(1:4)  = 0
222             req_count = 0
[1128]223
[683]224!
[1128]225!--          Send front boundary, receive rear one (asynchronous)
226             CALL MPI_ISEND( ar(nzb,nys,nxl-nbgp_local),   1, type_xz(grid_level), &
227                             psouth, req_count, comm2d, req(req_count+1), ierr )
228             CALL MPI_IRECV( ar(nzb,nyn+1,nxl-nbgp_local), 1, type_xz(grid_level), &
229                             pnorth, req_count, comm2d, req(req_count+2), ierr )
230!
231!--          Send rear boundary, receive front one (asynchronous)
[1320]232             CALL MPI_ISEND( ar(nzb,nyn-nbgp_local+1,nxl-nbgp_local), 1,       &
233                             type_xz(grid_level), pnorth, req_count+1, comm2d, &
[1128]234                             req(req_count+3), ierr )
[1320]235             CALL MPI_IRECV( ar(nzb,nys-nbgp_local,nxl-nbgp_local),   1,       &
236                             type_xz(grid_level), psouth, req_count+1, comm2d, &
[1128]237                             req(req_count+4), ierr )
[75]238
[2298]239             CALL MPI_WAITALL( 4, req, wait_stat, ierr )
[683]240
[1128]241          ENDIF
242
[683]243       ENDIF
244
[1]245    ENDIF
246
247#else
248
249!
[1113]250!-- Lateral boundary conditions in the non-parallel case.
251!-- Case dependent, because in GPU mode still not all arrays are on device. This
252!-- workaround has to be removed later. Also, since PGI compiler 12.5 has problems
253!-- with array syntax, explicit loops are used.
[1]254    IF ( bc_lr == 'cyclic' )  THEN
[2118]255       ar(:,:,nxl-nbgp_local:nxl-1) = ar(:,:,nxr-nbgp_local+1:nxr)
256       ar(:,:,nxr+1:nxr+nbgp_local) = ar(:,:,nxl:nxl+nbgp_local-1)
[1]257    ENDIF
258
259    IF ( bc_ns == 'cyclic' )  THEN
[2118]260       ar(:,nys-nbgp_local:nys-1,:) = ar(:,nyn-nbgp_local+1:nyn,:)
261       ar(:,nyn+1:nyn+nbgp_local,:) = ar(:,nys:nys+nbgp_local-1,:)
[1]262    ENDIF
263
264#endif
265    CALL cpu_log( log_point_s(2), 'exchange_horiz', 'stop' )
266
267 END SUBROUTINE exchange_horiz
[1677]268
269
[1682]270!------------------------------------------------------------------------------!
271! Description:
272! ------------
273!> @todo Missing subroutine description.
274!------------------------------------------------------------------------------!
[2696]275 SUBROUTINE exchange_horiz_int( ar, nys_l, nyn_l, nxl_l, nxr_l, nzt_l, nbgp_local)
[1677]276
277    USE control_parameters,                                                    &
[2696]278        ONLY:  bc_lr, bc_lr_cyc, bc_ns, bc_ns_cyc, grid_level
[1677]279                       
280    USE indices,                                                               &
281        ONLY:  nxl, nxr, nyn, nys, nzb, nzt
282       
283    USE kinds
284   
285    USE pegrid
286
287    IMPLICIT NONE
288
[2696]289    INTEGER(iwp) ::  nxl_l       !< local index bound at current grid level, left side
290    INTEGER(iwp) ::  nxr_l       !< local index bound at current grid level, right side
291    INTEGER(iwp) ::  nyn_l       !< local index bound at current grid level, north side
292    INTEGER(iwp) ::  nys_l       !< local index bound at current grid level, south side
293    INTEGER(iwp) ::  nzt_l       !< local index bound at current grid level, top
[1682]294    INTEGER(iwp) ::  nbgp_local  !< number of ghost points
[1677]295   
[2696]296    INTEGER(iwp), DIMENSION(nzb:nzt_l+1,nys_l-nbgp_local:nyn_l+nbgp_local,     &
297                            nxl_l-nbgp_local:nxr_l+nbgp_local) ::  ar  !< treated array
[1677]298
299
300#if defined( __parallel )
301    IF ( pdims(1) == 1 )  THEN
302!
303!--    One-dimensional decomposition along y, boundary values can be exchanged
304!--    within the PE memory
305       IF ( bc_lr_cyc )  THEN
[2696]306          ar(:,:,nxl_l-nbgp_local:nxl_l-1) = ar(:,:,nxr_l-nbgp_local+1:nxr_l)
307          ar(:,:,nxr_l+1:nxr_l+nbgp_local) = ar(:,:,nxl_l:nxl_l+nbgp_local-1)
[1677]308       ENDIF
309    ELSE
310!
311!--    Send left boundary, receive right one (synchronous)
[2696]312       CALL MPI_SENDRECV(                                                          &
313           ar(nzb,nys_l-nbgp_local,nxl_l),   1, type_yz_int(grid_level), pleft,  0,&
314           ar(nzb,nys_l-nbgp_local,nxr_l+1), 1, type_yz_int(grid_level), pright, 0,&
[1677]315           comm2d, status, ierr )
316!
317!--    Send right boundary, receive left one (synchronous)
[2696]318       CALL MPI_SENDRECV(                                                          &
319           ar(nzb,nys_l-nbgp_local,nxr_l+1-nbgp_local), 1, type_yz_int(grid_level),&
320           pright, 1,                                                              &
321           ar(nzb,nys_l-nbgp_local,nxl_l-nbgp_local),   1, type_yz_int(grid_level),&
322           pleft,  1,                                                              &
[1677]323           comm2d, status, ierr )
324    ENDIF
325
326
327    IF ( pdims(2) == 1 )  THEN
328!
329!--    One-dimensional decomposition along x, boundary values can be exchanged
330!--    within the PE memory
331       IF ( bc_ns_cyc )  THEN
[2696]332          ar(:,nys_l-nbgp_local:nys_l-1,:) = ar(:,nyn_l-nbgp_local+1:nyn_l,:)
333          ar(:,nyn_l+1:nyn_l+nbgp_local,:) = ar(:,nys_l:nys_l+nbgp_local-1,:)
[1677]334       ENDIF
335
336    ELSE
337
338!
339!--    Send front boundary, receive rear one (synchronous)
[2696]340       CALL MPI_SENDRECV(                                                          &
341           ar(nzb,nys_l,nxl_l-nbgp_local),   1, type_xz_int(grid_level), psouth, 0,&
342           ar(nzb,nyn_l+1,nxl_l-nbgp_local), 1, type_xz_int(grid_level), pnorth, 0,&
[1677]343           comm2d, status, ierr )
344!
345!--    Send rear boundary, receive front one (synchronous)
[2696]346       CALL MPI_SENDRECV( ar(nzb,nyn_l-nbgp_local+1,nxl_l-nbgp_local), 1,          &
347                          type_xz_int(grid_level), pnorth, 1,                      &
348                          ar(nzb,nys_l-nbgp_local,nxl_l-nbgp_local),   1,          &
349                          type_xz_int(grid_level), psouth, 1,                      &
[1677]350                          comm2d, status, ierr )
351
352    ENDIF
353
354#else
355
356    IF ( bc_lr == 'cyclic' )  THEN
[2696]357       ar(:,:,nxl_l-nbgp_local:nxl_l-1) = ar(:,:,nxr_l-nbgp_local+1:nxr_l)
358       ar(:,:,nxr_l+1:nxr_l+nbgp_local) = ar(:,:,nxl_l:nxl_l+nbgp_local-1)
[1677]359    ENDIF
360
361    IF ( bc_ns == 'cyclic' )  THEN
[2696]362       ar(:,nys_l-nbgp_local:nys_l-1,:) = ar(:,nyn_l-nbgp_local+1:nyn_l,:)
363       ar(:,nyn_l+1:nyn_l+nbgp_local,:) = ar(:,nys_l:nys_l+nbgp_local-1,:)
[1677]364    ENDIF
365
366#endif
367
368
[1933]369 END SUBROUTINE exchange_horiz_int
Note: See TracBrowser for help on using the repository browser.