source: palm/trunk/SOURCE/exchange_horiz_2d.f90 @ 3741

Last change on this file since 3741 was 3655, checked in by knoop, 6 years ago

Bugfix: made "unit" and "found" intend INOUT in module interface subroutines + automatic copyright update

  • Property svn:keywords set to Id
File size: 17.1 KB
RevLine 
[1682]1!> @file exchange_horiz_2d.f90
[2000]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!
[3655]17! Copyright 1997-2019 Leibniz Universitaet Hannover
[2000]18!------------------------------------------------------------------------------!
[1036]19!
[484]20! Current revisions:
[1]21! -----------------
[1683]22!
[3543]23!
[1321]24! Former revisions:
25! -----------------
26! $Id: exchange_horiz_2d.f90 3655 2019-01-07 16:51:22Z hellstea $
[3543]27! - New routine for exchange of 8-bit integer arrays
28! - Set Neumann conditions also at radiation boundary
29!
30! 3542 2018-11-20 17:04:13Z suehring
[3183]31! Rename variables in offline nesting mode and flags indicating lateral
32! boundary conditions
33!
34! 3182 2018-07-27 13:36:03Z suehring
[2716]35! Corrected "Former revisions" section
36!
37! 2696 2017-12-14 17:12:51Z kanani
38! Change in file header (GPL part)
[2696]39! Forcing implemented (MS)
40!
41! 2101 2017-01-05 16:42:31Z suehring
[1321]42!
[2001]43! 2000 2016-08-20 18:09:15Z knoop
44! Forced header and separation lines into 80 columns
45!
[1969]46! 1968 2016-07-18 12:01:49Z suehring
47! 2D-INTEGER exchange adopted for different multigrid level
48!
[1933]49! 1818 2016-04-06 15:53:27Z maronga
50! Initial version of purely vertical nesting introduced.
51!
[1805]52! 1804 2016-04-05 16:30:18Z maronga
53! Removed code for parameter file check (__check)
54!
[1763]55! 1762 2016-02-25 12:31:13Z hellstea
56! Introduction of nested domain feature
57!
[1683]58! 1682 2015-10-07 23:56:08Z knoop
59! Code annotations made doxygen readable
60!
[1349]61! 1348 2014-03-27 18:01:03Z raasch
62! bugfix: bc_lr_cyc and bc_ns_cyc added to ONLY-list
63!
[1321]64! 1320 2014-03-20 08:40:49Z raasch
[1320]65! ONLY-attribute added to USE-statements,
66! kind-parameters added to all INTEGER and REAL declaration statements,
67! kinds are defined in new module kinds,
68! revision history before 2012 removed,
69! comment fields (!:) to be used for variable explanations added to
70! all variable declaration statements
[1]71!
[1093]72! 1092 2013-02-02 11:24:22Z raasch
73! unused variables removed
74!
[1037]75! 1036 2012-10-22 13:43:42Z raasch
76! code put under GPL (PALM 3.9)
77!
[842]78! 841 2012-02-28 12:29:49Z maronga
79! Excluded routine from compilation of namelist_file_check
80!
[1]81! Revision 1.1  1998/01/23 09:58:21  raasch
82! Initial revision
83!
84!
85! Description:
86! ------------
[1682]87!> Exchange of lateral (ghost) boundaries (parallel computers) and cyclic
88!> boundary conditions, respectively, for 2D-arrays.
[1]89!------------------------------------------------------------------------------!
[1682]90 SUBROUTINE exchange_horiz_2d( ar )
91 
[1]92
[1320]93    USE control_parameters,                                                    &
[3182]94        ONLY :  bc_dirichlet_l, bc_dirichlet_n, bc_dirichlet_r,                &
95                bc_dirichlet_s, bc_lr_cyc, bc_ns_cyc, bc_radiation_l,          &
96                bc_radiation_n, bc_radiation_r, bc_radiation_s 
[1320]97               
98    USE cpulog,                                                                &
99        ONLY :  cpu_log, log_point_s
100       
101    USE indices,                                                               &
102        ONLY :  nbgp, nxl, nxlg, nxr, nxrg, nyn, nyng, nys, nysg
103       
104    USE kinds
105   
[1]106    USE pegrid
107
[1933]108    USE pmc_interface,                                                         &
109        ONLY : nesting_mode
110
111
[1]112    IMPLICIT NONE
113
[841]114
[1682]115    INTEGER(iwp) :: i  !<
[1320]116   
[1682]117    REAL(wp) ::  ar(nysg:nyng,nxlg:nxrg)  !<
[1320]118   
[1]119
120    CALL cpu_log( log_point_s(13), 'exchange_horiz_2d', 'start' )
121
122#if defined( __parallel )
123
124!
125!-- Exchange of lateral boundary values for parallel computers
126    IF ( pdims(1) == 1 )  THEN
127
128!
129!--    One-dimensional decomposition along y, boundary values can be exchanged
130!--    within the PE memory
[702]131       ar(:,nxlg:nxl-1) = ar(:,nxr-nbgp+1:nxr)
132       ar(:,nxr+1:nxrg) = ar(:,nxl:nxl+nbgp-1)
[1]133
134    ELSE
135!
136!--    Send left boundary, receive right one
[667]137
[702]138       CALL MPI_SENDRECV( ar(nysg,nxl), 1, type_y, pleft,  0,                 &
139                          ar(nysg,nxr+1), 1, type_y, pright, 0,               &
[1]140                          comm2d, status, ierr )
141!
142!--    Send right boundary, receive left one
[702]143       CALL MPI_SENDRECV( ar(nysg,nxr+1-nbgp), 1, type_y, pright,  1,         &
144                          ar(nysg,nxlg), 1, type_y, pleft,   1,               &
[1]145                          comm2d, status, ierr )
[702]146                         
147     
[1]148    ENDIF
149
150    IF ( pdims(2) == 1 )  THEN
151!
152!--    One-dimensional decomposition along x, boundary values can be exchanged
153!--    within the PE memory
[702]154       ar(nysg:nys-1,:) = ar(nyn-nbgp+1:nyn,:)
155       ar(nyn+1:nyng,:) = ar(nys:nys+nbgp-1,:)
[1]156
157    ELSE
158!
159!--    Send front boundary, receive rear one
[667]160
[702]161       CALL MPI_SENDRECV( ar(nys,nxlg), 1, type_x, psouth, 0,                 &         
162                          ar(nyn+1,nxlg), 1, type_x, pnorth, 0,               &
[1]163                          comm2d, status, ierr )
164!
165!--    Send rear boundary, receive front one
[702]166       CALL MPI_SENDRECV( ar(nyn+1-nbgp,nxlg), 1, type_x, pnorth, 1,          &
167                          ar(nysg,nxlg), 1, type_x, psouth, 1,                &
[1]168                          comm2d, status, ierr )
[667]169
[1]170    ENDIF
171
172#else
173
174!
175!-- Lateral boundary conditions in the non-parallel case
[707]176    IF ( bc_lr_cyc )  THEN
[702]177       ar(:,nxlg:nxl-1) = ar(:,nxr-nbgp+1:nxr)
178       ar(:,nxr+1:nxrg) = ar(:,nxl:nxl+nbgp-1)
[1]179    ENDIF
180
[707]181    IF ( bc_ns_cyc )  THEN
[702]182       ar(nysg:nys-1,:) = ar(nyn-nbgp+1:nyn,:)
183       ar(nyn+1:nyng,:) = ar(nys:nys+nbgp-1,:)
[1]184    ENDIF
185
[667]186
[1]187#endif
188
[73]189!
[1762]190!-- Neumann-conditions at inflow/outflow/nested boundaries
[1933]191    IF ( nesting_mode /= 'vertical' )  THEN
[3182]192       IF ( bc_dirichlet_l  .OR.  bc_radiation_l )  THEN
[1933]193          DO  i = nbgp, 1, -1
194             ar(:,nxl-i) = ar(:,nxl)
195          ENDDO
196       ENDIF
[3182]197       IF ( bc_dirichlet_r  .OR.  bc_radiation_r )  THEN
[1933]198          DO  i = 1, nbgp
199             ar(:,nxr+i) = ar(:,nxr)
200          ENDDO
201       ENDIF
[3182]202       IF ( bc_dirichlet_s  .OR.  bc_radiation_s )  THEN
[1933]203          DO  i = nbgp, 1, -1
204             ar(nys-i,:) = ar(nys,:)
205          ENDDO
206       ENDIF
[3182]207       IF ( bc_dirichlet_n  .OR.  bc_radiation_n )  THEN
[1933]208          DO  i = 1, nbgp
209             ar(nyn+i,:) = ar(nyn,:)
210          ENDDO
211       ENDIF
[1762]212    ENDIF
213
[1]214    CALL cpu_log( log_point_s(13), 'exchange_horiz_2d', 'stop' )
215
216 END SUBROUTINE exchange_horiz_2d
217
218
[3542]219!------------------------------------------------------------------------------!
220! Description:
221! ------------
222!> Exchange of lateral (ghost) boundaries (parallel computers) and cyclic
223!> boundary conditions, respectively, for 2D 8-bit integer arrays.
224!------------------------------------------------------------------------------!
225 SUBROUTINE exchange_horiz_2d_byte( ar, nys_l, nyn_l, nxl_l, nxr_l, nbgp_local )
[1]226
[3542]227
228    USE control_parameters,                                                    &
229        ONLY:  bc_dirichlet_l, bc_dirichlet_n, bc_dirichlet_r,                 &
230               bc_dirichlet_s, bc_radiation_l, bc_radiation_n, bc_radiation_r, &
231               bc_radiation_s, bc_lr_cyc, bc_ns_cyc, bc_radiation_l,           &
232               bc_radiation_n, bc_radiation_r, bc_radiation_s, grid_level
233       
234    USE cpulog,                                                                &
235        ONLY:  cpu_log, log_point_s
236               
237    USE kinds
238   
239    USE pegrid
240
241    IMPLICIT NONE
242
243    INTEGER(iwp) ::  i           !< dummy index to zero-gradient conditions at in/outflow boundaries
244    INTEGER(iwp) ::  nxl_l       !< local index bound at current grid level, left side
245    INTEGER(iwp) ::  nxr_l       !< local index bound at current grid level, right side
246    INTEGER(iwp) ::  nyn_l       !< local index bound at current grid level, north side
247    INTEGER(iwp) ::  nys_l       !< local index bound at current grid level, south side
248    INTEGER(iwp) ::  nbgp_local  !< number of ghost layers to be exchanged
249
250    INTEGER(KIND=1), DIMENSION(nys_l-nbgp_local:nyn_l+nbgp_local,              &
251                               nxl_l-nbgp_local:nxr_l+nbgp_local) ::  ar  !< treated array
252
253    CALL cpu_log( log_point_s(13), 'exchange_horiz_2d', 'start' )
254
255#if defined( __parallel )
256
257!
258!-- Exchange of lateral boundary values for parallel computers
259    IF ( pdims(1) == 1 )  THEN
260
261!
262!--    One-dimensional decomposition along y, boundary values can be exchanged
263!--    within the PE memory
264       ar(:,nxl_l-nbgp_local:nxl_l-1) = ar(:,nxr_l-nbgp_local+1:nxr_l)
265       ar(:,nxr_l+1:nxr_l+nbgp_local) = ar(:,nxl_l:nxl_l+nbgp_local-1)
266
267    ELSE
268!
269!--    Send left boundary, receive right one
270       CALL MPI_SENDRECV( ar(nys_l-nbgp_local,nxl_l),   1,                     &
271                          type_y_byte, pleft,  0,                              &
272                          ar(nys_l-nbgp_local,nxr_l+1), 1,                     &
273                          type_y_byte, pright, 0,                              &
274                          comm2d, status, ierr )
275!
276!--    Send right boundary, receive left one
277       CALL MPI_SENDRECV( ar(nys_l-nbgp_local,nxr_l+1-nbgp_local), 1,          &
278                          type_y_byte, pright, 1,                              &
279                          ar(nys_l-nbgp_local,nxl_l-nbgp_local),   1,          & 
280                          type_y_byte, pleft,  1,                              &
281                          comm2d, status, ierr )                         
282
283    ENDIF
284
285    IF ( pdims(2) == 1 )  THEN
286!
287!--    One-dimensional decomposition along x, boundary values can be exchanged
288!--    within the PE memory
289       ar(nys_l-nbgp_local:nys_l-1,:) = ar(nyn_l+1-nbgp_local:nyn_l,:)
290       ar(nyn_l+1:nyn_l+nbgp_local,:) = ar(nys_l:nys_l-1+nbgp_local,:)
291
292
293    ELSE
294!
295!--    Send front boundary, receive rear one
296       CALL MPI_SENDRECV( ar(nys_l,nxl_l-nbgp_local),   1,                    &
297                          type_x_byte, psouth, 0,                             &
298                          ar(nyn_l+1,nxl_l-nbgp_local), 1,                    &
299                          type_x_byte, pnorth, 0,                             &
300                          comm2d, status, ierr )                         
301
302!
303!--    Send rear boundary, receive front one
304       CALL MPI_SENDRECV( ar(nyn_l+1-nbgp_local,nxl_l-nbgp_local), 1,         &
305                          type_x_byte, pnorth, 1,                             &
306                          ar(nys_l-nbgp_local,nxl_l-nbgp_local),   1,         &
307                          type_x_byte, psouth, 1,                             &
308                          comm2d, status, ierr )
309
310    ENDIF
311
312#else
313
314!
315!-- Lateral boundary conditions in the non-parallel case
316    IF ( bc_lr_cyc )  THEN
317       ar(:,nxl_l-nbgp_local:nxl_l-1) = ar(:,nxr_l-nbgp_local+1:nxr_l)
318       ar(:,nxr_l+1:nxr_l+nbgp_local) = ar(:,nxl_l:nxl_l+nbgp_local-1)
319    ENDIF
320
321    IF ( bc_ns_cyc )  THEN
322       ar(nys_l-nbgp_local:nys_l-1,:) = ar(nyn_l+1-nbgp_local:nyn_l,:)
323       ar(nyn_l+1:nyn_l+nbgp_local,:) = ar(nys_l:nys_l-1+nbgp_local,:)
324    ENDIF
325
326#endif
327!
328!-- Neumann-conditions at inflow/outflow/nested boundaries
329    IF ( bc_dirichlet_l  .OR.  bc_radiation_l )  THEN
330       DO  i = nbgp_local, 1, -1
331         ar(:,nxl_l-i) = ar(:,nxl_l)
332       ENDDO
333    ENDIF
334    IF ( bc_dirichlet_r  .OR.  bc_radiation_r  )  THEN
335       DO  i = 1, nbgp_local
336          ar(:,nxr_l+i) = ar(:,nxr_l)
337       ENDDO
338    ENDIF
339    IF ( bc_dirichlet_s  .OR.  bc_radiation_s  )  THEN
340       DO  i = nbgp_local, 1, -1
341         ar(nys_l-i,:) = ar(nys_l,:)
342       ENDDO
343    ENDIF
344    IF ( bc_dirichlet_n  .OR.  bc_radiation_n  )  THEN
345       DO  i = 1, nbgp_local
346         ar(nyn_l+i,:) = ar(nyn_l,:)
347       ENDDO
348    ENDIF
349
350    CALL cpu_log( log_point_s(13), 'exchange_horiz_2d', 'stop' )
351
352 END SUBROUTINE exchange_horiz_2d_byte
353 
354
[1]355!------------------------------------------------------------------------------!
356! Description:
357! ------------
[1682]358!> Exchange of lateral (ghost) boundaries (parallel computers) and cyclic
[3542]359!> boundary conditions, respectively, for 2D 32-bit integer arrays.
[1]360!------------------------------------------------------------------------------!
[1968]361 SUBROUTINE exchange_horiz_2d_int( ar, nys_l, nyn_l, nxl_l, nxr_l, nbgp_local )
[1]362
[1682]363
[1320]364    USE control_parameters,                                                    &
[3182]365        ONLY:  bc_dirichlet_l, bc_dirichlet_n, bc_dirichlet_r,                 &
[3542]366               bc_dirichlet_s, bc_radiation_l, bc_radiation_n, bc_radiation_r, &
367               bc_radiation_s, bc_lr_cyc, bc_ns_cyc, bc_radiation_l,           &
[3182]368               bc_radiation_n, bc_radiation_r, bc_radiation_s, grid_level
[1320]369       
370    USE cpulog,                                                                &
371        ONLY:  cpu_log, log_point_s
[1968]372               
[1320]373    USE kinds
374   
[1]375    USE pegrid
376
377    IMPLICIT NONE
378
[1968]379    INTEGER(iwp) ::  i           !< dummy index to zero-gradient conditions at in/outflow boundaries
380    INTEGER(iwp) ::  nxl_l       !< local index bound at current grid level, left side
381    INTEGER(iwp) ::  nxr_l       !< local index bound at current grid level, right side
382    INTEGER(iwp) ::  nyn_l       !< local index bound at current grid level, north side
383    INTEGER(iwp) ::  nys_l       !< local index bound at current grid level, south side
384    INTEGER(iwp) ::  nbgp_local  !< number of ghost layers to be exchanged
[1]385
[1968]386    INTEGER(iwp), DIMENSION(nys_l-nbgp_local:nyn_l+nbgp_local,                 &
387                            nxl_l-nbgp_local:nxr_l+nbgp_local) ::  ar  !< treated array
388
[1]389    CALL cpu_log( log_point_s(13), 'exchange_horiz_2d', 'start' )
390
391#if defined( __parallel )
392
393!
394!-- Exchange of lateral boundary values for parallel computers
395    IF ( pdims(1) == 1 )  THEN
396
397!
398!--    One-dimensional decomposition along y, boundary values can be exchanged
399!--    within the PE memory
[1968]400       ar(:,nxl_l-nbgp_local:nxl_l-1) = ar(:,nxr_l-nbgp_local+1:nxr_l)
401       ar(:,nxr_l+1:nxr_l+nbgp_local) = ar(:,nxl_l:nxl_l+nbgp_local-1)
[1]402
403    ELSE
404!
405!--    Send left boundary, receive right one
[1968]406       CALL MPI_SENDRECV( ar(nys_l-nbgp_local,nxl_l),   1,                     &
407                          type_y_int(grid_level), pleft,  0,                   &
408                          ar(nys_l-nbgp_local,nxr_l+1), 1,                     &
409                          type_y_int(grid_level), pright, 0,                   &
[1]410                          comm2d, status, ierr )
411!
412!--    Send right boundary, receive left one
[1968]413       CALL MPI_SENDRECV( ar(nys_l-nbgp_local,nxr_l+1-nbgp_local), 1,          &
414                          type_y_int(grid_level), pright, 1,                   &
415                          ar(nys_l-nbgp_local,nxl_l-nbgp_local),   1,          & 
416                          type_y_int(grid_level), pleft,  1,                   &
417                          comm2d, status, ierr )                         
[667]418
[1]419    ENDIF
420
421    IF ( pdims(2) == 1 )  THEN
422!
423!--    One-dimensional decomposition along x, boundary values can be exchanged
424!--    within the PE memory
[1968]425       ar(nys_l-nbgp_local:nys_l-1,:) = ar(nyn_l+1-nbgp_local:nyn_l,:)
426       ar(nyn_l+1:nyn_l+nbgp_local,:) = ar(nys_l:nys_l-1+nbgp_local,:)
[1]427
[667]428
[1]429    ELSE
430!
431!--    Send front boundary, receive rear one
[1968]432       CALL MPI_SENDRECV( ar(nys_l,nxl_l-nbgp_local),   1,                    &
433                          type_x_int(grid_level), psouth, 0,                  &
434                          ar(nyn_l+1,nxl_l-nbgp_local), 1,                    &
435                          type_x_int(grid_level), pnorth, 0,                  &
[702]436                          comm2d, status, ierr )                         
[667]437
[1]438!
439!--    Send rear boundary, receive front one
[1968]440       CALL MPI_SENDRECV( ar(nyn_l+1-nbgp_local,nxl_l-nbgp_local), 1,         &
441                          type_x_int(grid_level), pnorth, 1,                  &
442                          ar(nys_l-nbgp_local,nxl_l-nbgp_local),   1,         &
443                          type_x_int(grid_level), psouth, 1,                  &
[1]444                          comm2d, status, ierr )
[667]445
[1]446    ENDIF
447
448#else
449
450!
451!-- Lateral boundary conditions in the non-parallel case
[707]452    IF ( bc_lr_cyc )  THEN
[1968]453       ar(:,nxl_l-nbgp_local:nxl_l-1) = ar(:,nxr_l-nbgp_local+1:nxr_l)
454       ar(:,nxr_l+1:nxr_l+nbgp_local) = ar(:,nxl_l:nxl_l+nbgp_local-1)
[1]455    ENDIF
456
[707]457    IF ( bc_ns_cyc )  THEN
[1968]458       ar(nys_l-nbgp_local:nys_l-1,:) = ar(nyn_l+1-nbgp_local:nyn_l,:)
459       ar(nyn_l+1:nyn_l+nbgp_local,:) = ar(nys_l:nys_l-1+nbgp_local,:)
[1]460    ENDIF
461
462#endif
[1762]463!
464!-- Neumann-conditions at inflow/outflow/nested boundaries
[3542]465    IF ( bc_dirichlet_l  .OR.  bc_radiation_l )  THEN
[1968]466       DO  i = nbgp_local, 1, -1
467         ar(:,nxl_l-i) = ar(:,nxl_l)
[1762]468       ENDDO
469    ENDIF
[3542]470    IF ( bc_dirichlet_r  .OR.  bc_radiation_r  )  THEN
[1968]471       DO  i = 1, nbgp_local
472          ar(:,nxr_l+i) = ar(:,nxr_l)
[1762]473       ENDDO
474    ENDIF
[3542]475    IF ( bc_dirichlet_s  .OR.  bc_radiation_s  )  THEN
[1968]476       DO  i = nbgp_local, 1, -1
477         ar(nys_l-i,:) = ar(nys_l,:)
[1762]478       ENDDO
479    ENDIF
[3542]480    IF ( bc_dirichlet_n  .OR.  bc_radiation_n  )  THEN
[1968]481       DO  i = 1, nbgp_local
482         ar(nyn_l+i,:) = ar(nyn_l,:)
[1762]483       ENDDO
484    ENDIF
485
[1]486    CALL cpu_log( log_point_s(13), 'exchange_horiz_2d', 'stop' )
487
488 END SUBROUTINE exchange_horiz_2d_int
Note: See TracBrowser for help on using the repository browser.