Index: palm/trunk/SOURCE/exchange_horiz_mod.f90
===================================================================
--- palm/trunk/SOURCE/exchange_horiz_mod.f90	(revision 4457)
+++ palm/trunk/SOURCE/exchange_horiz_mod.f90	(revision 4461)
@@ -25,4 +25,7 @@
 ! -----------------
 ! $Id$
+! optional communicator added to exchange_horiz
+! 
+! 4457 2020-03-11 14:20:43Z raasch
 ! routine has been modularized, file exchange_horiz_2d has been merged
 ! 
@@ -45,6 +48,6 @@
 ! Description:
 ! ------------
-!> Exchange of lateral boundary values (parallel computers) and cyclic
-!> lateral boundary conditions, respectively.
+!> Exchange of ghost point layers for subdomains (in parallel mode) and setting
+!> of cyclic lateral boundary conditions for the total domain .
 !------------------------------------------------------------------------------!
  MODULE exchange_horiz_mod
@@ -84,5 +87,12 @@
 
 
- SUBROUTINE exchange_horiz( ar, nbgp_local)
+!------------------------------------------------------------------------------!
+! Description:
+! ------------
+!> Exchange of ghost point layers for subdomains (in parallel mode) and setting
+!> of cyclic lateral boundary conditions for the total domain.
+!> This routine is for REAL 3d-arrays.
+!------------------------------------------------------------------------------!
+ SUBROUTINE exchange_horiz( ar, nbgp_local, alternative_communicator)
 
     USE control_parameters,                                                    &
@@ -105,8 +115,14 @@
 #endif
 
-    INTEGER(iwp) ::  nbgp_local  !<
+    INTEGER(iwp), OPTIONAL ::  alternative_communicator  !< alternative MPI communicator to be used
+    INTEGER(iwp) ::  communicator  !< communicator that is used as argument in MPI calls
+    INTEGER(iwp) ::  left_pe       !< id of left pe that is used as argument in MPI calls
+    INTEGER(iwp) ::  nbgp_local    !< number of ghost point layers
+    INTEGER(iwp) ::  north_pe      !< id of north pe that is used as argument in MPI calls
+    INTEGER(iwp) ::  right_pe      !< id of right pe that is used as argument in MPI calls
+    INTEGER(iwp) ::  south_pe      !< id of south pe that is used as argument in MPI calls
     
     REAL(wp), DIMENSION(nzb:nzt+1,nys-nbgp_local:nyn+nbgp_local,               &
-                        nxl-nbgp_local:nxr+nbgp_local) ::  ar  !<
+                        nxl-nbgp_local:nxr+nbgp_local) ::  ar !< 3d-array for which exchange is done
                         
 
@@ -136,4 +152,26 @@
 #endif
 
+!
+!-- Set the communicator to be used
+    IF ( PRESENT( alternative_communicator ) )  THEN
+!
+!--    Alternative communicator is to be used
+       communicator = communicator_configurations(alternative_communicator)%mpi_communicator
+       left_pe  = communicator_configurations(alternative_communicator)%pleft
+       right_pe = communicator_configurations(alternative_communicator)%pright
+       south_pe = communicator_configurations(alternative_communicator)%psouth
+       north_pe = communicator_configurations(alternative_communicator)%pnorth
+
+    ELSE
+!
+!--    Main communicator is to be used
+       communicator = comm2d
+       left_pe  = pleft
+       right_pe = pright
+       south_pe = psouth
+       north_pe = pnorth
+
+    ENDIF
+
 #if defined( __parallel )
 
@@ -154,15 +192,14 @@
 !
 !--       Send left boundary, receive right one (synchronous)
-          CALL MPI_SENDRECV(                                                   &
-              ar(nzb,nys-nbgp_local,nxl),   1, type_yz(grid_level), pleft,  0, &
-              ar(nzb,nys-nbgp_local,nxr+1), 1, type_yz(grid_level), pright, 0, &
-              comm2d, status, ierr )
+          CALL MPI_SENDRECV( ar(nzb,nys-nbgp_local,nxl),   1, type_yz(grid_level), left_pe,  0,    &
+                             ar(nzb,nys-nbgp_local,nxr+1), 1, type_yz(grid_level), right_pe, 0,    &
+                             communicator, status, ierr )
 !
 !--       Send right boundary, receive left one (synchronous)
-          CALL MPI_SENDRECV( ar(nzb,nys-nbgp_local,nxr+1-nbgp_local), 1,       &
-                             type_yz(grid_level), pright, 1,                   &
-                             ar(nzb,nys-nbgp_local,nxl-nbgp_local), 1,         &
-                             type_yz(grid_level), pleft,  1,                   &
-                             comm2d, status, ierr )
+          CALL MPI_SENDRECV( ar(nzb,nys-nbgp_local,nxr+1-nbgp_local), 1,                           &
+                             type_yz(grid_level), right_pe, 1,                                     &
+                             ar(nzb,nys-nbgp_local,nxl-nbgp_local), 1,                             &
+                             type_yz(grid_level), left_pe,  1,                                     &
+                             communicator, status, ierr )
 
        ELSE
@@ -176,16 +213,14 @@
 !
 !--          Send left boundary, receive right one (asynchronous)
-             CALL MPI_ISEND( ar(nzb,nys-nbgp_local,nxl),   1, type_yz(grid_level), &
-                             pleft, req_count, comm2d, req(req_count+1), ierr )
-             CALL MPI_IRECV( ar(nzb,nys-nbgp_local,nxr+1), 1, type_yz(grid_level), &
-                             pright, req_count, comm2d, req(req_count+2), ierr )
+             CALL MPI_ISEND( ar(nzb,nys-nbgp_local,nxl),   1, type_yz(grid_level), left_pe,        &
+                             req_count, communicator, req(req_count+1), ierr )
+             CALL MPI_IRECV( ar(nzb,nys-nbgp_local,nxr+1), 1, type_yz(grid_level), right_pe,       &
+                             req_count, communicator, req(req_count+2), ierr )
 !
 !--          Send right boundary, receive left one (asynchronous)
-             CALL MPI_ISEND( ar(nzb,nys-nbgp_local,nxr+1-nbgp_local), 1,       &
-                             type_yz(grid_level), pright, req_count+1, comm2d, &
-                             req(req_count+3), ierr )
-             CALL MPI_IRECV( ar(nzb,nys-nbgp_local,nxl-nbgp_local),   1,       &
-                             type_yz(grid_level), pleft,  req_count+1, comm2d, &
-                             req(req_count+4), ierr )
+             CALL MPI_ISEND( ar(nzb,nys-nbgp_local,nxr+1-nbgp_local), 1, type_yz(grid_level),      &
+                             right_pe, req_count+1, communicator, req(req_count+3), ierr )
+             CALL MPI_IRECV( ar(nzb,nys-nbgp_local,nxl-nbgp_local),   1, type_yz(grid_level),      &
+                             left_pe,  req_count+1, communicator, req(req_count+4), ierr )
 
              CALL MPI_WAITALL( 4, req, wait_stat, ierr )
@@ -219,15 +254,14 @@
 !
 !--       Send front boundary, receive rear one (synchronous)
-          CALL MPI_SENDRECV(                                                   &
-              ar(nzb,nys,nxl-nbgp_local),   1, type_xz(grid_level), psouth, 0, &
-              ar(nzb,nyn+1,nxl-nbgp_local), 1, type_xz(grid_level), pnorth, 0, &
-              comm2d, status, ierr )
+          CALL MPI_SENDRECV( ar(nzb,nys,nxl-nbgp_local),   1, type_xz(grid_level), south_pe, 0,    &
+                             ar(nzb,nyn+1,nxl-nbgp_local), 1, type_xz(grid_level), north_pe, 0,    &
+                             communicator, status, ierr )
 !
 !--       Send rear boundary, receive front one (synchronous)
-          CALL MPI_SENDRECV( ar(nzb,nyn-nbgp_local+1,nxl-nbgp_local), 1,       &
-                             type_xz(grid_level), pnorth, 1,                   &
-                             ar(nzb,nys-nbgp_local,nxl-nbgp_local),   1,       &
-                             type_xz(grid_level), psouth, 1,                   &
-                             comm2d, status, ierr )
+          CALL MPI_SENDRECV( ar(nzb,nyn-nbgp_local+1,nxl-nbgp_local), 1,                           &
+                             type_xz(grid_level), north_pe, 1,                                     &
+                             ar(nzb,nys-nbgp_local,nxl-nbgp_local),   1,                           &
+                             type_xz(grid_level), south_pe, 1,                                     &
+                             communicator, status, ierr )
 
        ELSE
@@ -242,16 +276,14 @@
 !
 !--          Send front boundary, receive rear one (asynchronous)
-             CALL MPI_ISEND( ar(nzb,nys,nxl-nbgp_local),   1, type_xz(grid_level), &
-                             psouth, req_count, comm2d, req(req_count+1), ierr )
-             CALL MPI_IRECV( ar(nzb,nyn+1,nxl-nbgp_local), 1, type_xz(grid_level), &
-                             pnorth, req_count, comm2d, req(req_count+2), ierr )
+             CALL MPI_ISEND( ar(nzb,nys,nxl-nbgp_local),   1, type_xz(grid_level), south_pe,       &
+                             req_count, communicator, req(req_count+1), ierr )
+             CALL MPI_IRECV( ar(nzb,nyn+1,nxl-nbgp_local), 1, type_xz(grid_level), north_pe,       &
+                             req_count, communicator, req(req_count+2), ierr )
 !
 !--          Send rear boundary, receive front one (asynchronous)
-             CALL MPI_ISEND( ar(nzb,nyn-nbgp_local+1,nxl-nbgp_local), 1,       &
-                             type_xz(grid_level), pnorth, req_count+1, comm2d, &
-                             req(req_count+3), ierr )
-             CALL MPI_IRECV( ar(nzb,nys-nbgp_local,nxl-nbgp_local),   1,       &
-                             type_xz(grid_level), psouth, req_count+1, comm2d, &
-                             req(req_count+4), ierr )
+             CALL MPI_ISEND( ar(nzb,nyn-nbgp_local+1,nxl-nbgp_local), 1, type_xz(grid_level),      &
+                             north_pe, req_count+1, communicator, req(req_count+3), ierr )
+             CALL MPI_IRECV( ar(nzb,nys-nbgp_local,nxl-nbgp_local),   1, type_xz(grid_level),      &
+                             south_pe, req_count+1, communicator, req(req_count+4), ierr )
 
              CALL MPI_WAITALL( 4, req, wait_stat, ierr )
