# Overview: MPIGrid

MPIGrid is a general class for storing a grid of any type across many tasks. Algorithms using this class generally assume the type is a field or ring type, i.e. it implements the arithmetic operations +,-,* and maybe / together with multiplication by a scalar, but that is no requirement. Just as with FFTWGrid, with MPI the grid cells are divided among the tasks accoring to their $x$ coordinate. Unfortunately I have not bothered to make the syntax for this class the same as for FFTWGrid which should be done. This class is useful, but it can be improved a lot (espesially on how we return data from it, right now its not very safe as all get methods give references and not just values which is bad). Its current use is mainly for our multigrid solver.

# Make a grid of your own type

Make a grid of your own type (a vector in each cell):

// A simple gridcell
typedef struct {
double vec[3];
double mass;
} GridCell;

// Make a grid of it
const int NDIM   = 3;
const int Nmesh  = 16;
const int nleft  = 1;
const int nright = 1;
const bool periodic = true;
FML::GRID::MPIGrid<NDIM, GridCell > grid(Nmesh, periodic, nleft, nright);


# Assign grid from a function

Make a grid containing doubles:

// Make a grid of it
const int NDIM   = 3;
const int Nmesh  = 16;
const int nleft  = 1;
const int nright = 1;
const bool periodic = true;
FML::GRID::MPIGrid<NDIM, double> grid(Nmesh, periodic, nleft, nright);

Assign the grid from a function:
// We want to set each gridcell equal to x+y+z
std::function<double(std::array<double,NDIM> &)> func = [](std::array<double,NDIM> & pos){
double value = 0.0;
for(int idim = 0; idim < NDIM; idim++)
value += pos[idim];
return value;
};

// Assign grid
grid.set_y(func);


# Accessing the data

There are several ways to access the data, see the headerfile. Here is an example:

// Get a pointer to the main grid
auto *y = grid.get_y();

// Loop through the grid
auto NtotLocal = grid.get_NtotLocal();
for(auto index = 0; index < NtotLocal; index++){
// Get coordinate of cell
auto coord = grid.coord_from_index(index);

// Get a list of the index of cells to the right/left top/bottom etc.
auto index_list = grid.get_neighbor_gridindex(index);

// Get the global position of the cell
auto pos = grid.get_pos(coord);
//...or grid.get_pos(index) if you don't have computed coord

// Set the value to 0
grid.set_y(index, 0.0);
}


# Communicate boundaries

To get the boundary values from neighboring tasks in the extra slices we must call:

grid.communicate_boundaries();