HyPar  1.0
Finite-Difference Hyperbolic-Parabolic PDE Solver on Cartesian Grids
MPIExchangeBoundaries1D.c File Reference

Exchange data and fill ghost points for a 1D array. More...

#include <stdlib.h>
#include <basic.h>
#include <arrayfunctions.h>
#include <mpivars.h>

Go to the source code of this file.

Functions

int MPIExchangeBoundaries1D (void *m, double *x, int N, int ghosts, int dir, int ndims)
 

Detailed Description

Exchange data and fill ghost points for a 1D array.

Author
Debojyoti Ghosh

Definition in file MPIExchangeBoundaries1D.c.

Function Documentation

◆ MPIExchangeBoundaries1D()

int MPIExchangeBoundaries1D ( void *  m,
double *  x,
int  N,
int  ghosts,
int  dir,
int  ndims 
)

Exchange the data across MPI ranks and fill in ghost points for a 1D array. In a multidimensional simulation, a 1D array is an array of data along one of the spatial dimensions, i.e. its an array storing a variable that varies in only one of the spatial dimension. For example, for a 2D problem on a Cartesian grid (with spatial dimensions x and y), the array of x-coordinates is a 1D array along x, and the array of y-coordinates is a 1D array along y. Thus, the size of the 1D array is equal to the size of the domain along the spatial dimension corresponding to that array.

Consider a two-dimensional problem, partitioned on 21 MPI ranks as follows:

mpi_ranks.png
and consider rank 9.

If the argument dir is specified as 0, and thus we are dealing with a 1D array along dimension 0, then

  • Rank 9 will exchange data with ranks 8 and 10, and fill in its ghost points.

If dir is specified as 1, and thus we are dealing with a 1D array along dimension 1, then

  • Rank 9 will exchange data with ranks 2 and 16, and fill in its ghost points.
Parameters
mMPI object of type MPIVariables
xThe 1D array for which to exchange data
NSize of the array
ghostsNumber of ghost points
dirSpatial dimension corresponding to the 1D array
ndimsNumber of spatial dimensions in the simulation

Definition at line 32 of file MPIExchangeBoundaries1D.c.

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 }
int MPIRank1D(int, int *, int *)
Definition: MPIRank1D.c:26
MPI_Comm world
Structure of MPI-related variables.
#define _ArrayCopy1D_(x, y, size)