#include "general.h"
#include "mpi.h"

#ifdef _PARALLEL
#define MASTER 0

class Distributor3D
{
/* Each node (domain) allocates full size array: double *f[NX*NY*NZ]
 *  but only update a sub-block of the array: [in0:in1-1, jn0:jn1-1, kn0:kn1-1]
 * So far Array can only split along one dimension specified by splitDim
 */
public: 
    int NX, NY, NZ;                   /* total size of array */
    int ndomX, ndomY, ndomZ;          /* number of domains in each direction */
    int splitDim;                     /* the direction to split the array: 0,1,2 for x,y,z */
    int nbuf;                         /* buffer size */
    int nDomains, domainID;           /* number of domains and domainID assigned by MPI */
    int idX, idY, idZ;                /* domain ID in 3D format */
    int in0, in1, jn0, jn1, kn0, kn1; /* limits of native domain */
    int ig0, ig1, jg0, jg1, kg0, kg1; /* limits of ghost domain */

    /* Constructor (set initial values of member variables) */
    Distributor3D(int nx, int ny, int nz, int ndx, int ndy, int ndz, int nb, int ndom, int dID);

    int pack_array_all(double *f, double *buf);
    int pack_array_native(double *f, double *buf);
    int unpack_array_all(double *f, double *buf);
    int unpack_array_native(double *f, double *buf);

    int distribute_array(double *f, double *buf);
    int collect_array(double *f, double *buf);
    int update_neighbor(double *f, double *buf);

};


#endif //_PARALLEL
