HyPar  1.0
Finite-Difference Hyperbolic-Parabolic PDE Solver on Cartesian Grids
MPIExchangeBoundaries1D.c
Go to the documentation of this file.
1 
6 #include <stdlib.h>
7 #include <basic.h>
8 #include <arrayfunctions.h>
9 #include <mpivars.h>
10 
33  void *m,
34  double *x,
35  int N,
36  int ghosts,
37  int dir,
38  int ndims
39  )
40 {
41 #ifndef serial
42  MPIVariables *mpi = (MPIVariables*) m;
43  int i;
44 
45  int *ip = mpi->ip;
46  int *iproc = mpi->iproc;
47  int non = 0; /* number of neighbours */
48 
49  int neighbor_rank[2] = {-1,-1};
50  int nip[ndims];
51 
52  /* each process has 2 neighbors (except at physical boundaries) */
53  /* calculate the rank of these neighbors (-1 -> none) */
54  _ArrayCopy1D_(ip,nip,ndims); nip[dir]--;
55  if (ip[dir] == 0) neighbor_rank[0] = -1;
56  else neighbor_rank[0] = MPIRank1D(ndims,iproc,nip);
57  _ArrayCopy1D_(ip,nip,ndims); nip[dir]++;
58  if (ip[dir] == (iproc[dir]-1))neighbor_rank[1] = -1;
59  else neighbor_rank[1] = MPIRank1D(ndims,iproc,nip);
60 
61  /* Allocate send and receive buffers */
62  double sendbuf[2][ghosts], recvbuf[2][ghosts];
63 
64  /* count number of neighbors and copy data to send buffers */
65  non = 0;
66  if (neighbor_rank[0] != -1) {
67  non++;
68  for (i = 0; i < ghosts; i++) sendbuf[0][i] = x[i+ghosts];
69  }
70  if (neighbor_rank[1] != -1) {
71  non++;
72  for (i = 0; i < ghosts; i++) sendbuf[1][i] = x[i+N];
73  }
74  MPI_Request requests[2*non];
75  MPI_Status statuses[2*non];
76 
77  /* exchange the data */
78  int tick = 0;
79  if (neighbor_rank[0]!= -1) {
80  MPI_Irecv(recvbuf[0],ghosts,MPI_DOUBLE,neighbor_rank[0],1631,mpi->world,&requests[tick]);
81  MPI_Isend(sendbuf[0],ghosts,MPI_DOUBLE,neighbor_rank[0],1631,mpi->world,&requests[tick+non]);
82  tick++;
83  }
84  if (neighbor_rank[1] != -1) {
85  MPI_Irecv(recvbuf[1],ghosts,MPI_DOUBLE,neighbor_rank[1],1631,mpi->world,&requests[tick]);
86  MPI_Isend(sendbuf[1],ghosts,MPI_DOUBLE,neighbor_rank[1],1631,mpi->world,&requests[tick+non]);
87  tick++;
88  }
89 
90  /* Wait till data transfer is done */
91  MPI_Waitall(2*non,requests,statuses);
92 
93  /* copy received data to ghost points */
94  if (neighbor_rank[0] != -1) for (i = 0; i < ghosts; i++) x[i] = recvbuf[0][i];
95  if (neighbor_rank[1] != -1) for (i = 0; i < ghosts; i++) x[i+N+ghosts] = recvbuf[1][i];
96 
97 #endif
98  return(0);
99 }
100 
MPI related function definitions.
Some basic definitions and macros.
int MPIRank1D(int, int *, int *)
Definition: MPIRank1D.c:26
MPI_Comm world
int MPIExchangeBoundaries1D(void *m, double *x, int N, int ghosts, int dir, int ndims)
Structure of MPI-related variables.
#define _ArrayCopy1D_(x, y, size)
Contains macros and function definitions for common array operations.